node-opcua-server-configuration 2.186.12 → 2.186.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/push_certificate_manager.d.ts +2 -0
- package/dist/push_certificate_manager.d.ts.map +1 -1
- package/dist/server/application_setup.d.ts +5 -0
- package/dist/server/application_setup.d.ts.map +1 -1
- package/dist/server/application_setup.js +7 -3
- package/dist/server/application_setup.js.map +1 -1
- package/dist/server/install_push_certificate_management.d.ts.map +1 -1
- package/dist/server/install_push_certificate_management.js +24 -1
- package/dist/server/install_push_certificate_management.js.map +1 -1
- package/dist/server/promote_trust_list.d.ts.map +1 -1
- package/dist/server/promote_trust_list.js +70 -32
- package/dist/server/promote_trust_list.js.map +1 -1
- package/dist/server/push_certificate_manager/create_signing_request.d.ts.map +1 -1
- package/dist/server/push_certificate_manager/create_signing_request.js +7 -1
- package/dist/server/push_certificate_manager/create_signing_request.js.map +1 -1
- package/dist/server/push_certificate_manager/get_rejected_list.d.ts +7 -0
- package/dist/server/push_certificate_manager/get_rejected_list.d.ts.map +1 -1
- package/dist/server/push_certificate_manager/get_rejected_list.js +7 -2
- package/dist/server/push_certificate_manager/get_rejected_list.js.map +1 -1
- package/dist/server/push_certificate_manager/internal_context.d.ts +6 -0
- package/dist/server/push_certificate_manager/internal_context.d.ts.map +1 -1
- package/dist/server/push_certificate_manager/internal_context.js +6 -0
- package/dist/server/push_certificate_manager/internal_context.js.map +1 -1
- package/dist/server/push_certificate_manager_server_impl.d.ts +15 -0
- package/dist/server/push_certificate_manager_server_impl.d.ts.map +1 -1
- package/dist/server/push_certificate_manager_server_impl.js +4 -0
- package/dist/server/push_certificate_manager_server_impl.js.map +1 -1
- package/dist/trust_list.d.ts +14 -14
- package/dist/trust_list.d.ts.map +1 -1
- package/package.json +8 -8
- package/source/push_certificate_manager.ts +2 -0
- package/source/server/application_setup.ts +8 -3
- package/source/server/install_push_certificate_management.ts +25 -1
- package/source/server/promote_trust_list.ts +86 -32
- package/source/server/push_certificate_manager/create_signing_request.ts +7 -1
- package/source/server/push_certificate_manager/get_rejected_list.ts +7 -2
- package/source/server/push_certificate_manager/internal_context.ts +10 -0
- package/source/server/push_certificate_manager_server_impl.ts +18 -0
- package/source/trust_list.ts +14 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal_context.d.ts","sourceRoot":"","sources":["../../../source/server/push_certificate_manager/internal_context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAExE,MAAM,MAAM,WAAW,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;AAElD,MAAM,WAAW,6BAA6B;IAC1C,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"internal_context.d.ts","sourceRoot":"","sources":["../../../source/server/push_certificate_manager/internal_context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAExE,MAAM,MAAM,WAAW,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;AAElD,MAAM,WAAW,6BAA6B;IAC1C,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,oHAAoH;IACpH,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,kHAAkH;IAClH,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IAEd,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAAC;IACpE,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IAC7D,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;CACjE;AAED,qBAAa,qCAAqC;IAQlC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPnC,SAAgB,GAAG,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAAA;KAAE,CAAM;IAChE,SAAgB,gBAAgB,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAM;IACnE,SAAgB,sBAAsB,yBAAgC;IAC/D,qBAAqB,CAAC,EAAE,kBAAkB,CAAC;IAC3C,WAAW,EAAE,WAAW,CAAM;IAC9B,mBAAmB,UAAS;IAEnC,YAA6B,MAAM,EAAE,6BAA6B,EAAI;IAEtE,IAAI,gBAAgB,mCAEnB;IACD,IAAI,cAAc,mCAEjB;IACD,IAAI,UAAU,mCAEb;IACD,IAAI,cAAc,WAEjB;IACD,IAAI,GAAG,yBAEN;IACD,IAAI,EAAE,yBAEL;IAED,qBAAqB,CAAC,SAAS,EAAE,MAAM,6BAEtC;IACD,mBAAmB,CAAC,SAAS,EAAE,MAAM,wBAEpC;IACD,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,WAElD;IAEY,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAWpC;CACJ"}
|
|
@@ -22,6 +22,12 @@ export class PushCertificateManagerInternalContext {
|
|
|
22
22
|
get applicationUri() {
|
|
23
23
|
return this.server.applicationUri;
|
|
24
24
|
}
|
|
25
|
+
get dns() {
|
|
26
|
+
return this.server.dns;
|
|
27
|
+
}
|
|
28
|
+
get ip() {
|
|
29
|
+
return this.server.ip;
|
|
30
|
+
}
|
|
25
31
|
getCertificateManager(groupName) {
|
|
26
32
|
return this.server.getCertificateManager(groupName);
|
|
27
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal_context.js","sourceRoot":"","sources":["../../../source/server/push_certificate_manager/internal_context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"internal_context.js","sourceRoot":"","sources":["../../../source/server/push_certificate_manager/internal_context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAmBxE,MAAM,OAAO,qCAAqC;IAQjB,MAAM;IAPnB,GAAG,GAA0C,EAAE,CAAC;IAChD,gBAAgB,GAAgC,EAAE,CAAC;IACnD,sBAAsB,GAAG,IAAI,sBAAsB,EAAE,CAAC;IAC/D,qBAAqB,CAAsB;IAC3C,WAAW,GAAgB,EAAE,CAAC;IAC9B,mBAAmB,GAAG,KAAK,CAAC;IAEnC,YAA6B,MAAqC;sBAArC,MAAM;IAAkC,CAAC;IAEtE,IAAI,gBAAgB;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC;IACxC,CAAC;IACD,IAAI,cAAc;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;IACtC,CAAC;IACD,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;IAClC,CAAC;IACD,IAAI,cAAc;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;IACtC,CAAC;IACD,IAAI,GAAG;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAC3B,CAAC;IACD,IAAI,EAAE;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IAC1B,CAAC;IAED,qBAAqB,CAAC,SAAiB;QACnC,OAAO,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IACxD,CAAC;IACD,mBAAmB,CAAC,SAAiB;QACjC,OAAO,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,CAAC,SAA0B,EAAE,GAAG,IAAe;QAC/C,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,CAAC;IAChD,CAAC;IAEM,KAAK,CAAC,OAAO;QAChB,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC7B,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,CAAC;YAC3C,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC;QAC3C,CAAC;QAED,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAC9B,MAAM,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,EAAE,CAAC;QACzD,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IAChC,CAAC;CACJ"}
|
|
@@ -31,6 +31,19 @@ export interface PushCertificateManagerServerOptions {
|
|
|
31
31
|
userTokenGroup?: CertificateManager;
|
|
32
32
|
httpsGroup?: CertificateManager;
|
|
33
33
|
applicationUri: string;
|
|
34
|
+
/**
|
|
35
|
+
* DNS host names and IP addresses to request in a CreateSigningRequest's
|
|
36
|
+
* SAN. Without these, a CSR only ever carries the ApplicationUri: some
|
|
37
|
+
* GDS/CA implementations then refuse the connection with
|
|
38
|
+
* BadCertificateHostNameInvalid once a client reaches the server by a
|
|
39
|
+
* hostname the certificate doesn't list. Pass the same values used for
|
|
40
|
+
* the server's own self-signed certificate (see
|
|
41
|
+
* `OPCUAServer.getConfiguredHostnames()`/`getConfiguredIPs()`, plus the
|
|
42
|
+
* machine's fqdn/hostname/auto-detected IPs) to keep a renewed
|
|
43
|
+
* certificate at parity with a fresh self-signed one.
|
|
44
|
+
*/
|
|
45
|
+
dns?: string[];
|
|
46
|
+
ip?: string[];
|
|
34
47
|
applicationGroupCertificateTypes?: NodeId[];
|
|
35
48
|
userTokenGroupCertificateTypes?: NodeId[];
|
|
36
49
|
httpsGroupCertificateTypes?: NodeId[];
|
|
@@ -40,6 +53,8 @@ export declare class PushCertificateManagerServerImpl extends EventEmitter imple
|
|
|
40
53
|
applicationGroup?: CertificateManager;
|
|
41
54
|
userTokenGroup?: CertificateManager;
|
|
42
55
|
httpsGroup?: CertificateManager;
|
|
56
|
+
dns?: string[];
|
|
57
|
+
ip?: string[];
|
|
43
58
|
private readonly _context;
|
|
44
59
|
/** @hidden */
|
|
45
60
|
applicationUri: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push_certificate_manager_server_impl.d.ts","sourceRoot":"","sources":["../../source/server/push_certificate_manager_server_impl.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,KAAK,EACR,0BAA0B,EAC1B,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EAC1B,MAAM,gCAAgC,CAAC;AASxC;;;;;;;;;GASG;AACH,MAAM,WAAW,4BAA4B;IACzC,qBAAqB,EAAE,CAAC,OAAO,CAAC,EAAE,eAAe,KAAK,IAAI,CAAC;IAC3D,kBAAkB,EAAE,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACvF,gBAAgB,EAAE,CAAC,kBAAkB,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,wBAAwB,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7D,kBAAkB,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAC;CAC1D;AAED,MAAM,WAAW,mCAAmC;IAChD,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAEhC,cAAc,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"push_certificate_manager_server_impl.d.ts","sourceRoot":"","sources":["../../source/server/push_certificate_manager_server_impl.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,8 @@ export class PushCertificateManagerServerImpl extends EventEmitter {
|
|
|
16
16
|
applicationGroup;
|
|
17
17
|
userTokenGroup;
|
|
18
18
|
httpsGroup;
|
|
19
|
+
dns;
|
|
20
|
+
ip;
|
|
19
21
|
// Use a true private reference (could be upgraded to #context in recent ES)
|
|
20
22
|
_context;
|
|
21
23
|
/** @hidden */
|
|
@@ -31,6 +33,8 @@ export class PushCertificateManagerServerImpl extends EventEmitter {
|
|
|
31
33
|
this._context = new PushCertificateManagerInternalContext(this);
|
|
32
34
|
this.applicationUri = options ? options.applicationUri : "";
|
|
33
35
|
if (options) {
|
|
36
|
+
this.dns = options.dns;
|
|
37
|
+
this.ip = options.ip;
|
|
34
38
|
this.applicationGroup = options.applicationGroup;
|
|
35
39
|
this.userTokenGroup = options.userTokenGroup;
|
|
36
40
|
this.httpsGroup = options.httpsGroup;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push_certificate_manager_server_impl.js","sourceRoot":"","sources":["../../source/server/push_certificate_manager_server_impl.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAIjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAO/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAClF,OAAO,EAAE,2BAA2B,EAAE,MAAM,sDAAsD,CAAC;AACnG,OAAO,EAAE,sBAAsB,EAAE,MAAM,iDAAiD,CAAC;AACzF,OAAO,EAAE,qCAAqC,EAAE,MAAM,gDAAgD,CAAC;AACvG,OAAO,EAAE,wBAAwB,EAAE,MAAM,kDAAkD,CAAC;AAE5F,MAAM,QAAQ,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"push_certificate_manager_server_impl.js","sourceRoot":"","sources":["../../source/server/push_certificate_manager_server_impl.ts"],"names":[],"mappings":"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"}
|
package/dist/trust_list.d.ts
CHANGED
|
@@ -36,21 +36,19 @@ export interface ITrustList {
|
|
|
36
36
|
*
|
|
37
37
|
* If an invalid Certificate is found the Server shall return an error and shall not update the Trust List.
|
|
38
38
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
39
|
+
* The Method returns a validation error if the Certificate is issued by a CA and the
|
|
40
|
+
* Certificate for the issuer is not in the Trust List. Issuer Certificates cannot be added
|
|
41
|
+
* with this Method: they are written, with their CRLs, through Open/Write/CloseAndUpdate.
|
|
41
42
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* This method cannot be called if the file object is open
|
|
47
|
-
* @param certificate - The DER encoded Certificate to add as a ByteStrng
|
|
48
|
-
* @param isTrustedCerticopy ficate - If TRUE the Certificate is added to the Trusted Certificates List. If FALSE the Certificate is added to the Issuer Certificates List.
|
|
43
|
+
* This method cannot be called if the file object is open (OPC 10000-12 §7.8.2.6).
|
|
44
|
+
* @param certificate - The DER encoded Certificate to add as a ByteString
|
|
45
|
+
* @param isTrustedCertificate - If TRUE the Certificate is added to the Trusted Certificates List. If FALSE BadCertificateInvalid is returned.
|
|
49
46
|
*
|
|
50
47
|
* **Result Code**
|
|
51
48
|
* - BadUserAccessDenied: The current user does not have the rights required.
|
|
52
49
|
* - BadCertificateInvalid: The certificate to add is invalid.
|
|
53
|
-
* - BadInvalidState: The object is
|
|
50
|
+
* - BadInvalidState: The object is open for write and CloseAndUpdate has not been called.
|
|
51
|
+
* - BadNotWritable: The object is open for read only.
|
|
54
52
|
*
|
|
55
53
|
*/
|
|
56
54
|
addCertificate(certificate: Buffer, isTrustedCertificate: boolean): Promise<StatusCode>;
|
|
@@ -61,16 +59,18 @@ export interface ITrustList {
|
|
|
61
59
|
*
|
|
62
60
|
* If the Certificate is a CA Certificate with associated CRLs then all CRLs are removed as well.
|
|
63
61
|
*
|
|
64
|
-
* This method cannot be called if the file object is open.
|
|
62
|
+
* This method cannot be called if the file object is open (OPC 10000-12 §7.8.2.7).
|
|
65
63
|
*
|
|
66
64
|
* @param thumbprint - The SHA1 hash of the Certificate to remove
|
|
67
65
|
* @param isTrustedCertificate - If TRUE the Certificate is removed from the Trusted Certificates List.
|
|
68
66
|
* If FALSE the Certificate is removed from the Issuer Certificates List.
|
|
69
67
|
*
|
|
70
68
|
* **Result Code**
|
|
71
|
-
* -BadUserAccessDenied:
|
|
72
|
-
* -BadInvalidArgument:
|
|
73
|
-
* -
|
|
69
|
+
* -BadUserAccessDenied: The current user does not have the rights required.
|
|
70
|
+
* -BadInvalidArgument: The certificate to remove was not found.
|
|
71
|
+
* -BadCertificateChainIncomplete: The Certificate is needed to validate another Certificate in the Trust List.
|
|
72
|
+
* -BadInvalidState: The object is open for write and CloseAndUpdate has not been called.
|
|
73
|
+
* -BadNotWritable: The object is open for read only.
|
|
74
74
|
*
|
|
75
75
|
*
|
|
76
76
|
*/
|
package/dist/trust_list.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trust_list.d.ts","sourceRoot":"","sources":["../source/trust_list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,cAAc,CAEV,oBAAoB,EAAE,OAAO,GAC9B,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB
|
|
1
|
+
{"version":3,"file":"trust_list.d.ts","sourceRoot":"","sources":["../source/trust_list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,cAAc,CAEV,oBAAoB,EAAE,OAAO,GAC9B,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAExF;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC7F"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-opcua-server-configuration",
|
|
3
|
-
"version": "2.186.
|
|
3
|
+
"version": "2.186.14",
|
|
4
4
|
"description": "pure nodejs OPCUA SDK - module server-configuration",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "tsc -b",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"chalk": "6.0.1",
|
|
20
20
|
"memfs": "^4.79.0",
|
|
21
|
-
"node-opcua-address-space": "2.186.
|
|
21
|
+
"node-opcua-address-space": "2.186.14",
|
|
22
22
|
"node-opcua-address-space-base": "2.186.10",
|
|
23
23
|
"node-opcua-assert": "2.186.7",
|
|
24
24
|
"node-opcua-basic-types": "2.186.7",
|
|
@@ -29,13 +29,13 @@
|
|
|
29
29
|
"node-opcua-crypto": "6.1.2",
|
|
30
30
|
"node-opcua-data-model": "2.186.10",
|
|
31
31
|
"node-opcua-debug": "2.186.7",
|
|
32
|
-
"node-opcua-file-transfer": "2.186.
|
|
32
|
+
"node-opcua-file-transfer": "2.186.14",
|
|
33
33
|
"node-opcua-hostname": "2.184.0",
|
|
34
34
|
"node-opcua-nodeid": "2.186.7",
|
|
35
35
|
"node-opcua-pki": "7.0.1",
|
|
36
|
-
"node-opcua-pseudo-session": "2.186.
|
|
37
|
-
"node-opcua-secure-channel": "2.186.
|
|
38
|
-
"node-opcua-server": "2.186.
|
|
36
|
+
"node-opcua-pseudo-session": "2.186.14",
|
|
37
|
+
"node-opcua-secure-channel": "2.186.14",
|
|
38
|
+
"node-opcua-server": "2.186.14",
|
|
39
39
|
"node-opcua-service-translate-browse-path": "2.186.10",
|
|
40
40
|
"node-opcua-status-code": "2.186.7",
|
|
41
41
|
"node-opcua-types": "2.186.10",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"bcryptjs": "3.0.3",
|
|
47
|
-
"node-opcua-client": "2.186.
|
|
47
|
+
"node-opcua-client": "2.186.14",
|
|
48
48
|
"node-opcua-data-value": "2.186.10",
|
|
49
49
|
"node-opcua-leak-detector": "2.186.7",
|
|
50
50
|
"node-opcua-nodesets": "2.185.0"
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"internet of things"
|
|
65
65
|
],
|
|
66
66
|
"homepage": "http://node-opcua.github.io/",
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "faa1ad65879893a681cd561ae616f0c403d6ba7a",
|
|
68
68
|
"files": [
|
|
69
69
|
"dist",
|
|
70
70
|
"source"
|
|
@@ -145,6 +145,8 @@ export interface PushCertificateManager {
|
|
|
145
145
|
|
|
146
146
|
/**
|
|
147
147
|
* GetRejectedList Method returns the list of Certificates that have been rejected by the Server.
|
|
148
|
+
* It is a shortcut for the GetRejectedList Method on the DefaultApplicationGroup CertificateGroup
|
|
149
|
+
* (OPC 10000-12 §7.10.12): Certificates rejected by the other CertificateGroups are not returned.
|
|
148
150
|
* No rules are defined for how the Server updates this list or how long a Certificate is kept in
|
|
149
151
|
* the list. It is recommended that every valid but untrusted Certificate be added to the rejected
|
|
150
152
|
* list as long as storage is available. Servers should omit older entries from the list returned if
|
|
@@ -101,19 +101,24 @@ export async function confirmTrust(cm: CertificateManager, list: ProvisionalList
|
|
|
101
101
|
* parsed is skipped with a warning rather than failing the caller.
|
|
102
102
|
*/
|
|
103
103
|
export async function leafThumbprintsIn(folder: string): Promise<string[]> {
|
|
104
|
+
return (await leafCertificatesIn(folder)).map((entry) => entry.thumbprint);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** The leaf certificate of each certificate file in a PKI folder, with its thumbprint, skipping what does not parse. */
|
|
108
|
+
export async function leafCertificatesIn(folder: string): Promise<{ thumbprint: string; certificate: Buffer }[]> {
|
|
104
109
|
if (!fs.existsSync(folder)) return [];
|
|
105
|
-
const
|
|
110
|
+
const entries: { thumbprint: string; certificate: Buffer }[] = [];
|
|
106
111
|
for (const file of await fs.promises.readdir(folder)) {
|
|
107
112
|
const ext = path.extname(file);
|
|
108
113
|
if (ext !== ".der" && ext !== ".pem") continue;
|
|
109
114
|
try {
|
|
110
115
|
const chain = await readCertificateChainAsync(path.join(folder, file));
|
|
111
|
-
if (chain.length > 0)
|
|
116
|
+
if (chain.length > 0) entries.push({ thumbprint: makeSHA1Thumbprint(chain[0]).toString("hex"), certificate: chain[0] });
|
|
112
117
|
} catch (err) {
|
|
113
118
|
warningLog(`[TrustList] skipping ${path.join(folder, file)}: not a certificate`, (err as Error).message);
|
|
114
119
|
}
|
|
115
120
|
}
|
|
116
|
-
return
|
|
121
|
+
return entries;
|
|
117
122
|
}
|
|
118
123
|
|
|
119
124
|
/** Whether the trusted list holds at least one certificate that was not trusted provisionally. */
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
} from "node-opcua-crypto/web";
|
|
26
26
|
import { addProfileUri } from "node-opcua-data-model";
|
|
27
27
|
import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
|
|
28
|
+
import { getFullyQualifiedDomainName, getHostname, getIpAddresses } from "node-opcua-hostname";
|
|
28
29
|
import type { OPCUAServer, OPCUAServerEndPoint } from "node-opcua-server";
|
|
29
30
|
import { type StatusCode, StatusCodes } from "node-opcua-status-code";
|
|
30
31
|
import { type ApplicationDescriptionOptions, ServerState } from "node-opcua-types";
|
|
@@ -60,6 +61,26 @@ export interface OPCUAServerPartial extends ICertificateKeyPairProvider {
|
|
|
60
61
|
getCertificateChainProvider(): ICertificateChainProvider;
|
|
61
62
|
}
|
|
62
63
|
|
|
64
|
+
/**
|
|
65
|
+
* The DNS host names and IP addresses a CreateSigningRequest asks a GDS to
|
|
66
|
+
* put in a renewed certificate's SAN, matching exactly what the server's own
|
|
67
|
+
* self-signed certificate already carries (`BaseServer.createDefaultCertificate`):
|
|
68
|
+
* the machine's fqdn/hostname plus whatever `alternateHostname`/
|
|
69
|
+
* `advertisedEndpoints` configured, and auto-detected plus configured IPs.
|
|
70
|
+
*
|
|
71
|
+
* Without this, a CSR only ever requests the ApplicationUri: some GDS/CA
|
|
72
|
+
* implementations then issue a certificate a hostname-verifying client
|
|
73
|
+
* refuses with BadCertificateHostNameInvalid, because the certificate lists
|
|
74
|
+
* no DNS/IP to match the connection address against.
|
|
75
|
+
*/
|
|
76
|
+
function collectCertificateSanValues(server: OPCUAServer): { dns: string[]; ip: string[] } {
|
|
77
|
+
const fqdn = getFullyQualifiedDomainName();
|
|
78
|
+
const hostname = getHostname();
|
|
79
|
+
const dns = [...new Set([fqdn, hostname, ...server.getConfiguredHostnames()])].sort();
|
|
80
|
+
const ip = [...new Set([...getIpAddresses(), ...server.getConfiguredIPs()])].sort();
|
|
81
|
+
return { dns, ip };
|
|
82
|
+
}
|
|
83
|
+
|
|
63
84
|
async function onCertificateAboutToChange(server: OPCUAServer) {
|
|
64
85
|
doDebug && debugLog(chalk.yellow(" onCertificateAboutToChange => Suspending End points"));
|
|
65
86
|
await server.suspendEndPoints();
|
|
@@ -329,11 +350,14 @@ export async function installPushCertificateManagementOnServer(
|
|
|
329
350
|
endpoint.setCertificateProvider(provider);
|
|
330
351
|
}
|
|
331
352
|
|
|
353
|
+
const { dns, ip } = collectCertificateSanValues(server);
|
|
332
354
|
await installPushCertificateManagement(server.engine.addressSpace, {
|
|
333
355
|
applicationGroup: cm,
|
|
334
356
|
userTokenGroup: server.userCertificateManager,
|
|
335
357
|
|
|
336
|
-
applicationUri: server.serverInfo.applicationUri || "InvalidURI"
|
|
358
|
+
applicationUri: server.serverInfo.applicationUri || "InvalidURI",
|
|
359
|
+
dns,
|
|
360
|
+
ip
|
|
337
361
|
});
|
|
338
362
|
|
|
339
363
|
const serverConfiguration = server.engine.addressSpace.rootFolder.objects.server.getChildByName("ServerConfiguration");
|
|
@@ -21,7 +21,13 @@ import type {
|
|
|
21
21
|
} from "node-opcua-address-space";
|
|
22
22
|
import { BinaryStream } from "node-opcua-binary-stream";
|
|
23
23
|
import type { OPCUACertificateManager } from "node-opcua-certificate-manager";
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
exploreCertificate,
|
|
26
|
+
makeSHA1Thumbprint,
|
|
27
|
+
split_der,
|
|
28
|
+
verifyCertificateChain,
|
|
29
|
+
verifyCertificateSignature
|
|
30
|
+
} from "node-opcua-crypto/web";
|
|
25
31
|
import { AccessRestrictionsFlag } from "node-opcua-data-model";
|
|
26
32
|
import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
|
|
27
33
|
import { type AbstractFs, installFileType, OpenFileMode } from "node-opcua-file-transfer";
|
|
@@ -29,7 +35,7 @@ import { VerificationStatus } from "node-opcua-pki";
|
|
|
29
35
|
import { type CallbackT, type StatusCode, StatusCodes } from "node-opcua-status-code";
|
|
30
36
|
import { type CallMethodResultOptions, TrustListDataType } from "node-opcua-types";
|
|
31
37
|
import { DataType, Variant } from "node-opcua-variant";
|
|
32
|
-
import { confirmTrust, isSharedTrustListStore, leafThumbprintsIn } from "./application_setup.js";
|
|
38
|
+
import { confirmTrust, isSharedTrustListStore, leafCertificatesIn, leafThumbprintsIn } from "./application_setup.js";
|
|
33
39
|
import type { PushCertificateManagerServerImpl } from "./push_certificate_manager_server_impl.js";
|
|
34
40
|
import { rolePermissionAdminOnly } from "./roles_and_permissions.js";
|
|
35
41
|
import { hasEncryptedChannel, hasExpectedUserAccess } from "./tools.js";
|
|
@@ -81,6 +87,57 @@ function trustListIsAlreadyOpened(trustList: UATrustList): boolean {
|
|
|
81
87
|
return openCount > 0;
|
|
82
88
|
}
|
|
83
89
|
|
|
90
|
+
/**
|
|
91
|
+
* AddCertificate and RemoveCertificate "cannot be called if the containing
|
|
92
|
+
* TrustList Object is open" (OPC 10000-12 §7.8.2.6, §7.8.2.7). Their result
|
|
93
|
+
* tables tell the two cases apart: open with write access is Bad_InvalidState,
|
|
94
|
+
* open for read only is Bad_NotWritable.
|
|
95
|
+
*/
|
|
96
|
+
function statusWhenOpen(trustList: UATrustListEx): StatusCode | undefined {
|
|
97
|
+
if (trustList.$$openedForWrite) {
|
|
98
|
+
return StatusCodes.BadInvalidState;
|
|
99
|
+
}
|
|
100
|
+
if (trustListIsAlreadyOpened(trustList)) {
|
|
101
|
+
return StatusCodes.BadNotWritable;
|
|
102
|
+
}
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
type TrustListStore = "trusted" | "issuers";
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Whether removing `thumbprint` from `store` would leave another Certificate
|
|
110
|
+
* of the TrustList without an issuer able to validate it (§7.8.2.7:
|
|
111
|
+
* Bad_CertificateChainIncomplete). Both lists count, so an intermediate CA in
|
|
112
|
+
* the Issuer list keeps its root. A copy of the same CA kept in the other
|
|
113
|
+
* list, or another CA with the same key, still validates the child.
|
|
114
|
+
*/
|
|
115
|
+
async function isNeededToValidateAnother(
|
|
116
|
+
cm: OPCUACertificateManager,
|
|
117
|
+
store: TrustListStore,
|
|
118
|
+
thumbprint: string,
|
|
119
|
+
certificate: Buffer
|
|
120
|
+
): Promise<boolean> {
|
|
121
|
+
const entries = [
|
|
122
|
+
...(await leafCertificatesIn(cm.trustedFolder)).map((e) => ({ ...e, store: "trusted" })),
|
|
123
|
+
...(await leafCertificatesIn(cm.issuersCertFolder)).map((e) => ({ ...e, store: "issuers" }))
|
|
124
|
+
];
|
|
125
|
+
const remaining = entries.filter((e) => !(e.store === store && e.thumbprint === thumbprint));
|
|
126
|
+
const signedBy = (child: Buffer, issuer: Buffer) => {
|
|
127
|
+
try {
|
|
128
|
+
return verifyCertificateSignature(child, issuer);
|
|
129
|
+
} catch {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
return remaining.some(
|
|
134
|
+
(child) =>
|
|
135
|
+
child.thumbprint !== thumbprint &&
|
|
136
|
+
signedBy(child.certificate, certificate) &&
|
|
137
|
+
!remaining.some((other) => other.thumbprint !== child.thumbprint && signedBy(child.certificate, other.certificate))
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
84
141
|
/**
|
|
85
142
|
* Update the mandatory LastUpdateTime property whenever the trust list is modified.
|
|
86
143
|
* Per OPC UA Part 12 spec, this must be updated after AddCertificate, RemoveCertificate, or CloseAndUpdate.
|
|
@@ -536,8 +593,9 @@ async function _addCertificate(
|
|
|
536
593
|
if (!cm) {
|
|
537
594
|
return { statusCode: StatusCodes.BadInternalError };
|
|
538
595
|
}
|
|
539
|
-
|
|
540
|
-
|
|
596
|
+
const openStatus = statusWhenOpen(trustList);
|
|
597
|
+
if (openStatus) {
|
|
598
|
+
return { statusCode: openStatus };
|
|
541
599
|
}
|
|
542
600
|
|
|
543
601
|
const certificateBuffer: Buffer = inputArguments[0].value as Buffer;
|
|
@@ -593,8 +651,9 @@ async function _removeCertificate(
|
|
|
593
651
|
return { statusCode: StatusCodes.BadInternalError };
|
|
594
652
|
}
|
|
595
653
|
|
|
596
|
-
|
|
597
|
-
|
|
654
|
+
const openStatus = statusWhenOpen(trustList);
|
|
655
|
+
if (openStatus) {
|
|
656
|
+
return { statusCode: openStatus };
|
|
598
657
|
}
|
|
599
658
|
|
|
600
659
|
const thumbprint: string = inputArguments[0].value as string;
|
|
@@ -604,33 +663,28 @@ async function _removeCertificate(
|
|
|
604
663
|
// Normalize thumbprint - remove "NodeOPCUA[" prefix if present
|
|
605
664
|
const normalizedThumbprint = thumbprint.replace(/^NodeOPCUA\[|\]$/g, "").toLowerCase();
|
|
606
665
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
warningLog("Certificate is needed for chain validation");
|
|
627
|
-
return { statusCode: StatusCodes.BadCertificateChainIncomplete };
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
// Also remove CRLs issued by this CA
|
|
631
|
-
await cm.removeRevocationListsForIssuer(issuerCert, "issuers");
|
|
632
|
-
await confirmTrust(cm, "issuers", [normalizedThumbprint]);
|
|
666
|
+
// §7.8.2.7, the same rules for both lists: Bad_InvalidArgument when
|
|
667
|
+
// the thumbprint is not in the list, Bad_CertificateChainIncomplete
|
|
668
|
+
// when another Certificate still needs it, checked before anything is
|
|
669
|
+
// removed, and a CA's CRLs leave with it.
|
|
670
|
+
const store: TrustListStore = isTrustedCertificate ? "trusted" : "issuers";
|
|
671
|
+
const folder = isTrustedCertificate ? cm.trustedFolder : cm.issuersCertFolder;
|
|
672
|
+
const certificate = (await leafCertificatesIn(folder)).find((e) => e.thumbprint === normalizedThumbprint)?.certificate;
|
|
673
|
+
if (!certificate) {
|
|
674
|
+
return { statusCode: StatusCodes.BadInvalidArgument };
|
|
675
|
+
}
|
|
676
|
+
if (await isNeededToValidateAnother(cm, store, normalizedThumbprint, certificate)) {
|
|
677
|
+
warningLog("Certificate is needed for chain validation");
|
|
678
|
+
return { statusCode: StatusCodes.BadCertificateChainIncomplete };
|
|
679
|
+
}
|
|
680
|
+
const removed = isTrustedCertificate
|
|
681
|
+
? await cm.removeTrustedCertificate(normalizedThumbprint)
|
|
682
|
+
: await cm.removeIssuer(normalizedThumbprint);
|
|
683
|
+
if (!removed) {
|
|
684
|
+
return { statusCode: StatusCodes.BadInvalidArgument };
|
|
633
685
|
}
|
|
686
|
+
await cm.removeRevocationListsForIssuer(certificate, store);
|
|
687
|
+
await confirmTrust(cm, store, [normalizedThumbprint]);
|
|
634
688
|
|
|
635
689
|
updateLastUpdateTime(trustList);
|
|
636
690
|
emitTrustListUpdated(trustList);
|
|
@@ -132,7 +132,13 @@ export async function executeCreateSigningRequest(
|
|
|
132
132
|
try {
|
|
133
133
|
const options = {
|
|
134
134
|
applicationUri: serverImpl.applicationUri,
|
|
135
|
-
subject: subjectName
|
|
135
|
+
subject: subjectName,
|
|
136
|
+
// Without these, the CSR only ever carries the ApplicationUri in
|
|
137
|
+
// its SAN. Some GDS/CA implementations then refuse a connection
|
|
138
|
+
// reaching the server by hostname with BadCertificateHostNameInvalid,
|
|
139
|
+
// since the issued certificate lists no DNS/IP to match against.
|
|
140
|
+
dns: serverImpl.dns,
|
|
141
|
+
ip: serverImpl.ip
|
|
136
142
|
};
|
|
137
143
|
|
|
138
144
|
const activeCertificateManager = serverImpl.tmpCertificateManager || certificateManager;
|
|
@@ -38,12 +38,17 @@ async function extractRejectedList(group: CertificateManager | undefined, certif
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* ServerConfiguration.GetRejectedList "is a shortcut for the GetRejectedList
|
|
43
|
+
* Method on the DefaultApplicationGroup CertificateGroup" (OPC 10000-12
|
|
44
|
+
* §7.10.12), so only that group's rejected Certificates are returned. A
|
|
45
|
+
* rejected user token or HTTPS Certificate is not one a Client can move into
|
|
46
|
+
* the DefaultApplicationGroup TrustList.
|
|
47
|
+
*/
|
|
41
48
|
export async function executeGetRejectedList(serverImpl: PushCertificateManagerInternalContext): Promise<GetRejectedListResult> {
|
|
42
49
|
const list: FileData[] = [];
|
|
43
50
|
|
|
44
51
|
await extractRejectedList(serverImpl.applicationGroup, list);
|
|
45
|
-
await extractRejectedList(serverImpl.userTokenGroup, list);
|
|
46
|
-
await extractRejectedList(serverImpl.httpsGroup, list);
|
|
47
52
|
|
|
48
53
|
// sort list from newer file to older file
|
|
49
54
|
list.sort((a: FileData, b: FileData) => b.stat.mtime.getTime() - a.stat.mtime.getTime());
|
|
@@ -9,6 +9,10 @@ export interface IPushCertificateManagerServer {
|
|
|
9
9
|
userTokenGroup?: CertificateManager;
|
|
10
10
|
httpsGroup?: CertificateManager;
|
|
11
11
|
applicationUri: string;
|
|
12
|
+
/** DNS host names to request in a CreateSigningRequest's SAN, matching the server's own self-signed certificate. */
|
|
13
|
+
dns?: string[];
|
|
14
|
+
/** IP addresses to request in a CreateSigningRequest's SAN, matching the server's own self-signed certificate. */
|
|
15
|
+
ip?: string[];
|
|
12
16
|
|
|
13
17
|
getCertificateManager(groupName: string): CertificateManager | null;
|
|
14
18
|
getCertificateTypes(groupName: string): NodeId[] | undefined;
|
|
@@ -37,6 +41,12 @@ export class PushCertificateManagerInternalContext {
|
|
|
37
41
|
get applicationUri() {
|
|
38
42
|
return this.server.applicationUri;
|
|
39
43
|
}
|
|
44
|
+
get dns() {
|
|
45
|
+
return this.server.dns;
|
|
46
|
+
}
|
|
47
|
+
get ip() {
|
|
48
|
+
return this.server.ip;
|
|
49
|
+
}
|
|
40
50
|
|
|
41
51
|
getCertificateManager(groupName: string) {
|
|
42
52
|
return this.server.getCertificateManager(groupName);
|
|
@@ -50,6 +50,20 @@ export interface PushCertificateManagerServerOptions {
|
|
|
50
50
|
|
|
51
51
|
applicationUri: string;
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* DNS host names and IP addresses to request in a CreateSigningRequest's
|
|
55
|
+
* SAN. Without these, a CSR only ever carries the ApplicationUri: some
|
|
56
|
+
* GDS/CA implementations then refuse the connection with
|
|
57
|
+
* BadCertificateHostNameInvalid once a client reaches the server by a
|
|
58
|
+
* hostname the certificate doesn't list. Pass the same values used for
|
|
59
|
+
* the server's own self-signed certificate (see
|
|
60
|
+
* `OPCUAServer.getConfiguredHostnames()`/`getConfiguredIPs()`, plus the
|
|
61
|
+
* machine's fqdn/hostname/auto-detected IPs) to keep a renewed
|
|
62
|
+
* certificate at parity with a fresh self-signed one.
|
|
63
|
+
*/
|
|
64
|
+
dns?: string[];
|
|
65
|
+
ip?: string[];
|
|
66
|
+
|
|
53
67
|
// Optional: Allowed certificate types for each group
|
|
54
68
|
// These should be read from the CertificateTypes Property of the CertificateGroup objects in the AddressSpace
|
|
55
69
|
// If not provided, defaults to all known OPC UA certificate types (backward compatibility)
|
|
@@ -64,6 +78,8 @@ export class PushCertificateManagerServerImpl extends EventEmitter implements Pu
|
|
|
64
78
|
public applicationGroup?: CertificateManager;
|
|
65
79
|
public userTokenGroup?: CertificateManager;
|
|
66
80
|
public httpsGroup?: CertificateManager;
|
|
81
|
+
public dns?: string[];
|
|
82
|
+
public ip?: string[];
|
|
67
83
|
|
|
68
84
|
// Use a true private reference (could be upgraded to #context in recent ES)
|
|
69
85
|
private readonly _context: PushCertificateManagerInternalContext;
|
|
@@ -91,6 +107,8 @@ export class PushCertificateManagerServerImpl extends EventEmitter implements Pu
|
|
|
91
107
|
this.applicationUri = options ? options.applicationUri : "";
|
|
92
108
|
|
|
93
109
|
if (options) {
|
|
110
|
+
this.dns = options.dns;
|
|
111
|
+
this.ip = options.ip;
|
|
94
112
|
this.applicationGroup = options.applicationGroup;
|
|
95
113
|
this.userTokenGroup = options.userTokenGroup;
|
|
96
114
|
this.httpsGroup = options.httpsGroup;
|