@project-chip/matter.js 0.9.1 → 0.9.3
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/cjs/MatterDevice.d.ts +1 -0
- package/dist/cjs/MatterDevice.d.ts.map +1 -1
- package/dist/cjs/MatterDevice.js +3 -0
- package/dist/cjs/MatterDevice.js.map +2 -2
- package/dist/cjs/model/models/AttributeModel.d.ts +1 -0
- package/dist/cjs/model/models/AttributeModel.d.ts.map +1 -1
- package/dist/cjs/model/models/AttributeModel.js +3 -1
- package/dist/cjs/model/models/AttributeModel.js.map +2 -2
- package/dist/cjs/node/server/TransactionalInteractionServer.d.ts.map +1 -1
- package/dist/cjs/node/server/TransactionalInteractionServer.js +15 -2
- package/dist/cjs/node/server/TransactionalInteractionServer.js.map +2 -2
- package/dist/cjs/protocol/ChannelManager.js +1 -1
- package/dist/cjs/protocol/ChannelManager.js.map +2 -2
- package/dist/cjs/protocol/interaction/InteractionServer.d.ts +6 -0
- package/dist/cjs/protocol/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/cjs/protocol/interaction/InteractionServer.js +79 -22
- package/dist/cjs/protocol/interaction/InteractionServer.js.map +2 -2
- package/dist/cjs/protocol/securechannel/SecureChannelProtocol.d.ts.map +1 -1
- package/dist/cjs/protocol/securechannel/SecureChannelProtocol.js +4 -2
- package/dist/cjs/protocol/securechannel/SecureChannelProtocol.js.map +2 -2
- package/dist/cjs/session/SecureSession.d.ts.map +1 -1
- package/dist/cjs/session/SecureSession.js +2 -1
- package/dist/cjs/session/SecureSession.js.map +2 -2
- package/dist/cjs/session/SessionManager.d.ts +1 -0
- package/dist/cjs/session/SessionManager.d.ts.map +1 -1
- package/dist/cjs/session/SessionManager.js +7 -0
- package/dist/cjs/session/SessionManager.js.map +2 -2
- package/dist/esm/MatterDevice.d.ts +1 -0
- package/dist/esm/MatterDevice.d.ts.map +1 -1
- package/dist/esm/MatterDevice.js +3 -0
- package/dist/esm/MatterDevice.js.map +2 -2
- package/dist/esm/model/models/AttributeModel.d.ts +1 -0
- package/dist/esm/model/models/AttributeModel.d.ts.map +1 -1
- package/dist/esm/model/models/AttributeModel.js +3 -1
- package/dist/esm/model/models/AttributeModel.js.map +2 -2
- package/dist/esm/node/server/TransactionalInteractionServer.d.ts.map +1 -1
- package/dist/esm/node/server/TransactionalInteractionServer.js +15 -2
- package/dist/esm/node/server/TransactionalInteractionServer.js.map +2 -2
- package/dist/esm/protocol/ChannelManager.js +1 -1
- package/dist/esm/protocol/ChannelManager.js.map +2 -2
- package/dist/esm/protocol/interaction/InteractionServer.d.ts +6 -0
- package/dist/esm/protocol/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/esm/protocol/interaction/InteractionServer.js +79 -22
- package/dist/esm/protocol/interaction/InteractionServer.js.map +2 -2
- package/dist/esm/protocol/securechannel/SecureChannelProtocol.d.ts.map +1 -1
- package/dist/esm/protocol/securechannel/SecureChannelProtocol.js +4 -2
- package/dist/esm/protocol/securechannel/SecureChannelProtocol.js.map +2 -2
- package/dist/esm/session/SecureSession.d.ts.map +1 -1
- package/dist/esm/session/SecureSession.js +2 -1
- package/dist/esm/session/SecureSession.js.map +2 -2
- package/dist/esm/session/SessionManager.d.ts +1 -0
- package/dist/esm/session/SessionManager.d.ts.map +1 -1
- package/dist/esm/session/SessionManager.js +7 -0
- package/dist/esm/session/SessionManager.js.map +2 -2
- package/package.json +3 -3
- package/src/MatterDevice.ts +4 -0
- package/src/model/models/AttributeModel.ts +2 -0
- package/src/node/server/TransactionalInteractionServer.ts +21 -6
- package/src/protocol/ChannelManager.ts +1 -1
- package/src/protocol/interaction/InteractionServer.ts +91 -24
- package/src/protocol/securechannel/SecureChannelProtocol.ts +3 -1
- package/src/session/SecureSession.ts +2 -1
- package/src/session/SessionManager.ts +8 -0
|
@@ -27,6 +27,7 @@ var import_Logger = require("../../log/Logger.js");
|
|
|
27
27
|
var import_SecureSession = require("../../session/SecureSession.js");
|
|
28
28
|
var import_CaseServer = require("../../session/case/CaseServer.js");
|
|
29
29
|
var import_PaseServer = require("../../session/pase/PaseServer.js");
|
|
30
|
+
var import_StatusCode = require("../interaction/StatusCode.js");
|
|
30
31
|
var import_SecureChannelMessages = require("./SecureChannelMessages.js");
|
|
31
32
|
var import_SecureChannelMessenger = require("./SecureChannelMessenger.js");
|
|
32
33
|
var import_SecureChannelStatusMessageSchema = require("./SecureChannelStatusMessageSchema.js");
|
|
@@ -47,8 +48,9 @@ class StatusReportOnlySecureChannelProtocol {
|
|
|
47
48
|
await this.handleInitialStatusReport(exchange, message);
|
|
48
49
|
break;
|
|
49
50
|
default:
|
|
50
|
-
throw new
|
|
51
|
-
`Unexpected initial message on secure channel protocol: ${messageType.toString(16)}
|
|
51
|
+
throw new import_StatusCode.StatusResponseError(
|
|
52
|
+
`Unexpected initial message on secure channel protocol: ${messageType.toString(16)}`,
|
|
53
|
+
import_StatusCode.StatusCode.InvalidAction
|
|
52
54
|
);
|
|
53
55
|
}
|
|
54
56
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/protocol/securechannel/SecureChannelProtocol.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Message } from \"../../codec/MessageCodec.js\";\nimport { MatterFlowError } from \"../../common/MatterError.js\";\nimport { Logger } from \"../../log/Logger.js\";\nimport { MessageExchange } from \"../../protocol/MessageExchange.js\";\nimport { ProtocolHandler } from \"../../protocol/ProtocolHandler.js\";\nimport { assertSecureSession } from \"../../session/SecureSession.js\";\nimport { CaseServer } from \"../../session/case/CaseServer.js\";\nimport { MaximumPasePairingErrorsReachedError, PaseServer } from \"../../session/pase/PaseServer.js\";\nimport {\n GeneralStatusCode,\n MessageType,\n ProtocolStatusCode,\n SECURE_CHANNEL_PROTOCOL_ID,\n} from \"./SecureChannelMessages.js\";\nimport { ChannelStatusResponseError, SecureChannelMessenger } from \"./SecureChannelMessenger.js\";\nimport { TlvSecureChannelStatusMessage } from \"./SecureChannelStatusMessageSchema.js\";\n\nconst logger = Logger.get(\"SecureChannelProtocol\");\n\nexport class StatusReportOnlySecureChannelProtocol implements ProtocolHandler<any> {\n getId(): number {\n return SECURE_CHANNEL_PROTOCOL_ID;\n }\n\n async onNewExchange(exchange: MessageExchange<any>, message: Message) {\n const messageType = message.payloadHeader.messageType;\n\n switch (messageType) {\n case MessageType.StatusReport:\n await this.handleInitialStatusReport(exchange, message);\n break;\n default:\n throw new
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,yBAAgC;AAChC,oBAAuB;AAGvB,2BAAoC;AACpC,wBAA2B;AAC3B,wBAAiE;AACjE,mCAKO;AACP,oCAAmE;AACnE,8CAA8C;
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Message } from \"../../codec/MessageCodec.js\";\nimport { MatterFlowError } from \"../../common/MatterError.js\";\nimport { Logger } from \"../../log/Logger.js\";\nimport { MessageExchange } from \"../../protocol/MessageExchange.js\";\nimport { ProtocolHandler } from \"../../protocol/ProtocolHandler.js\";\nimport { assertSecureSession } from \"../../session/SecureSession.js\";\nimport { CaseServer } from \"../../session/case/CaseServer.js\";\nimport { MaximumPasePairingErrorsReachedError, PaseServer } from \"../../session/pase/PaseServer.js\";\nimport { StatusCode, StatusResponseError } from \"../interaction/StatusCode.js\";\nimport {\n GeneralStatusCode,\n MessageType,\n ProtocolStatusCode,\n SECURE_CHANNEL_PROTOCOL_ID,\n} from \"./SecureChannelMessages.js\";\nimport { ChannelStatusResponseError, SecureChannelMessenger } from \"./SecureChannelMessenger.js\";\nimport { TlvSecureChannelStatusMessage } from \"./SecureChannelStatusMessageSchema.js\";\n\nconst logger = Logger.get(\"SecureChannelProtocol\");\n\nexport class StatusReportOnlySecureChannelProtocol implements ProtocolHandler<any> {\n getId(): number {\n return SECURE_CHANNEL_PROTOCOL_ID;\n }\n\n async onNewExchange(exchange: MessageExchange<any>, message: Message) {\n const messageType = message.payloadHeader.messageType;\n\n switch (messageType) {\n case MessageType.StatusReport:\n await this.handleInitialStatusReport(exchange, message);\n break;\n default:\n throw new StatusResponseError(\n `Unexpected initial message on secure channel protocol: ${messageType.toString(16)}`,\n StatusCode.InvalidAction,\n );\n }\n }\n\n async handleInitialStatusReport(exchange: MessageExchange<any>, message: Message) {\n const {\n payloadHeader: { messageType },\n payload,\n } = message;\n if (messageType !== MessageType.StatusReport) {\n throw new MatterFlowError(\n `Unexpected message type on secure channel protocol, expected StatusReport: ${messageType.toString(\n 16,\n )}`,\n );\n }\n\n const { generalStatus, protocolId, protocolStatus } = TlvSecureChannelStatusMessage.decode(payload);\n if (generalStatus !== GeneralStatusCode.Success) {\n throw new ChannelStatusResponseError(\n `Received general error status (${protocolId})`,\n generalStatus,\n protocolStatus,\n );\n }\n if (protocolStatus !== ProtocolStatusCode.CloseSession) {\n throw new ChannelStatusResponseError(\n `Received general success status, but protocol status is not CloseSession`,\n generalStatus,\n protocolStatus,\n );\n }\n\n const { session } = exchange;\n assertSecureSession(session);\n logger.debug(`Peer requested to close session ${session.name}. Remove session now.`);\n // TODO: and do more - see Core Specs 5.5\n await session.destroy(false, false);\n }\n\n async close() {\n // Nothing to do\n }\n}\n\nexport class SecureChannelProtocol extends StatusReportOnlySecureChannelProtocol {\n private paseCommissioner: PaseServer | undefined;\n private readonly caseCommissioner = new CaseServer();\n\n constructor(private commissioningCancelledCallback: () => Promise<void>) {\n super();\n }\n\n setPaseCommissioner(paseServer: PaseServer) {\n this.paseCommissioner = paseServer;\n }\n\n removePaseCommissioner() {\n this.paseCommissioner = undefined;\n }\n\n override async onNewExchange(exchange: MessageExchange<any>, message: Message) {\n const messageType = message.payloadHeader.messageType;\n\n switch (messageType) {\n case MessageType.PbkdfParamRequest:\n if (this.paseCommissioner === undefined) {\n // Cleaner to return an error (ok for chip-tool as it seems)?\n // Formally we should not respond at all which leads to retries and such\n const messenger = new SecureChannelMessenger(exchange);\n await messenger.sendError(ProtocolStatusCode.InvalidParam);\n await messenger.close(); // also closes exchange\n return;\n }\n try {\n await this.paseCommissioner.onNewExchange(exchange);\n } catch (error) {\n if (error instanceof MaximumPasePairingErrorsReachedError) {\n logger.info(\"Maximum number of PASE pairing errors reached, cancelling commissioning.\");\n await this.commissioningCancelledCallback();\n } else {\n throw error;\n }\n }\n break;\n case MessageType.Sigma1:\n await this.caseCommissioner.onNewExchange(exchange);\n break;\n default:\n await super.onNewExchange(exchange, message);\n }\n }\n\n static isStandaloneAck(protocolId: number, messageType: number) {\n return protocolId === SECURE_CHANNEL_PROTOCOL_ID && messageType === MessageType.StandaloneAck;\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,yBAAgC;AAChC,oBAAuB;AAGvB,2BAAoC;AACpC,wBAA2B;AAC3B,wBAAiE;AACjE,wBAAgD;AAChD,mCAKO;AACP,oCAAmE;AACnE,8CAA8C;AAtB9C;AAAA;AAAA;AAAA;AAAA;AAwBA,MAAM,SAAS,qBAAO,IAAI,uBAAuB;AAE1C,MAAM,sCAAsE;AAAA,EAC/E,QAAgB;AACZ,WAAO;AAAA,EACX;AAAA,EAEA,MAAM,cAAc,UAAgC,SAAkB;AAClE,UAAM,cAAc,QAAQ,cAAc;AAE1C,YAAQ,aAAa;AAAA,MACjB,KAAK,yCAAY;AACb,cAAM,KAAK,0BAA0B,UAAU,OAAO;AACtD;AAAA,MACJ;AACI,cAAM,IAAI;AAAA,UACN,0DAA0D,YAAY,SAAS,EAAE,CAAC;AAAA,UAClF,6BAAW;AAAA,QACf;AAAA,IACR;AAAA,EACJ;AAAA,EAEA,MAAM,0BAA0B,UAAgC,SAAkB;AAC9E,UAAM;AAAA,MACF,eAAe,EAAE,YAAY;AAAA,MAC7B;AAAA,IACJ,IAAI;AACJ,QAAI,gBAAgB,yCAAY,cAAc;AAC1C,YAAM,IAAI;AAAA,QACN,8EAA8E,YAAY;AAAA,UACtF;AAAA,QACJ,CAAC;AAAA,MACL;AAAA,IACJ;AAEA,UAAM,EAAE,eAAe,YAAY,eAAe,IAAI,sEAA8B,OAAO,OAAO;AAClG,QAAI,kBAAkB,+CAAkB,SAAS;AAC7C,YAAM,IAAI;AAAA,QACN,kCAAkC,UAAU;AAAA,QAC5C;AAAA,QACA;AAAA,MACJ;AAAA,IACJ;AACA,QAAI,mBAAmB,gDAAmB,cAAc;AACpD,YAAM,IAAI;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACJ;AAAA,IACJ;AAEA,UAAM,EAAE,QAAQ,IAAI;AACpB,kDAAoB,OAAO;AAC3B,WAAO,MAAM,mCAAmC,QAAQ,IAAI,uBAAuB;AAEnF,UAAM,QAAQ,QAAQ,OAAO,KAAK;AAAA,EACtC;AAAA,EAEA,MAAM,QAAQ;AAAA,EAEd;AACJ;AAEO,MAAM,8BAA8B,sCAAsC;AAAA,EAI7E,YAAoB,gCAAqD;AACrE,UAAM;AADU;AAFpB,SAAiB,mBAAmB,IAAI,6BAAW;AAAA,EAInD;AAAA,EAEA,oBAAoB,YAAwB;AACxC,SAAK,mBAAmB;AAAA,EAC5B;AAAA,EAEA,yBAAyB;AACrB,SAAK,mBAAmB;AAAA,EAC5B;AAAA,EAEA,MAAe,cAAc,UAAgC,SAAkB;AAC3E,UAAM,cAAc,QAAQ,cAAc;AAE1C,YAAQ,aAAa;AAAA,MACjB,KAAK,yCAAY;AACb,YAAI,KAAK,qBAAqB,QAAW;AAGrC,gBAAM,YAAY,IAAI,qDAAuB,QAAQ;AACrD,gBAAM,UAAU,UAAU,gDAAmB,YAAY;AACzD,gBAAM,UAAU,MAAM;AACtB;AAAA,QACJ;AACA,YAAI;AACA,gBAAM,KAAK,iBAAiB,cAAc,QAAQ;AAAA,QACtD,SAAS,OAAO;AACZ,cAAI,iBAAiB,wDAAsC;AACvD,mBAAO,KAAK,0EAA0E;AACtF,kBAAM,KAAK,+BAA+B;AAAA,UAC9C,OAAO;AACH,kBAAM;AAAA,UACV;AAAA,QACJ;AACA;AAAA,MACJ,KAAK,yCAAY;AACb,cAAM,KAAK,iBAAiB,cAAc,QAAQ;AAClD;AAAA,MACJ;AACI,cAAM,MAAM,cAAc,UAAU,OAAO;AAAA,IACnD;AAAA,EACJ;AAAA,EAEA,OAAO,gBAAgB,YAAoB,aAAqB;AAC5D,WAAO,eAAe,2DAA8B,gBAAgB,yCAAY;AAAA,EACpF;AACJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecureSession.d.ts","sourceRoot":"","sources":["../../../src/session/SecureSession.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAgB,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAGxG,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAK7C,OAAO,EAAc,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,EAAE,mBAAmB,EAAE,MAAM,gDAAgD,CAAC;AACrF,OAAO,EAAE,SAAS,EAAU,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAOhE,qBAAa,uBAAwB,SAAQ,mBAAmB;gBAChD,OAAO,EAAE,MAAM;CAG9B;AAED,qBAAa,aAAa,CAAC,CAAC,CAAE,SAAQ,OAAO,CAAC,CAAC,CAAC;;WAe/B,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE;QACzB,OAAO,EAAE,CAAC,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,SAAS,CAAC;QACxB,IAAI,EAAE,SAAS,CAAC;QAChB,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,EAAE,OAAO,CAAC;QACtB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,2BAA2B,CAAC,EAAE,MAAM,IAAI,CAAC;QACzC,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;KAClD;gBA0CW,IAAI,EAAE;QACd,OAAO,EAAE,CAAC,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,SAAS,CAAC;QACtB,UAAU,EAAE,SAAS,CAAC;QACtB,cAAc,EAAE,SAAS,CAAC;QAC1B,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,2BAA2B,CAAC,EAAE,MAAM,IAAI,CAAC;QACzC,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;QAC/C,WAAW,EAAE,OAAO,CAAC;KACxB;IAiDD,IAAI,qBAAqB,2BAExB;IAED,IAAI,4BAA4B,YAE/B;IAED,IAAI,2BAA2B,YAE9B;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAEK,KAAK,CAAC,0BAA0B,CAAC,EAAE,OAAO;IAOhD,MAAM,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,cAAc;IAiBvG,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAYhC,0BAA0B,IAAI,SAAS;IAIvC,IAAI,MAAM,uBAET;IAED,mBAAmB,CAAC,MAAM,EAAE,MAAM;IAQlC,IAAI,EAAE,WAEL;IAED,IAAI,IAAI,WAEP;IAED,IAAI,OAAO,MAEV;IAED,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,IAAI,MAAM,WAET;IAED,IAAI,UAAU,WAEb;IAED,IAAI,2BAA2B,WAE9B;IAED,IAAI,gBAAgB,IAAI,MAAM,CAO7B;IAED,eAAe,CAAC,YAAY,EAAE,mBAAmB;IAMjD,kBAAkB,CAAC,cAAc,EAAE,MAAM;IASnC,kBAAkB,CAAC,kBAAkB,UAAQ;
|
|
1
|
+
{"version":3,"file":"SecureSession.d.ts","sourceRoot":"","sources":["../../../src/session/SecureSession.ts"],"names":[],"mappings":"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"}
|
|
@@ -248,7 +248,8 @@ class SecureSession extends import_Session.Session {
|
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
async clearSubscriptions(flushSubscriptions = false) {
|
|
251
|
-
|
|
251
|
+
const subscriptions = [...this.#subscriptions];
|
|
252
|
+
for (const subscription of subscriptions) {
|
|
252
253
|
await subscription.cancel(flushSubscriptions);
|
|
253
254
|
}
|
|
254
255
|
this.#subscriptions.length = 0;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/session/SecureSession.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { DecodedMessage, DecodedPacket, Message, MessageCodec, Packet } from \"../codec/MessageCodec.js\";\nimport { MatterFlowError } from \"../common/MatterError.js\";\nimport { CRYPTO_SYMMETRIC_KEY_LENGTH, Crypto } from \"../crypto/Crypto.js\";\nimport { CaseAuthenticatedTag } from \"../datatype/CaseAuthenticatedTag.js\";\nimport { NodeId } from \"../datatype/NodeId.js\";\nimport { Fabric } from \"../fabric/Fabric.js\";\nimport { Diagnostic } from \"../log/Diagnostic.js\";\nimport { Logger } from \"../log/Logger.js\";\nimport { MessageCounter } from \"../protocol/MessageCounter.js\";\nimport { MessageReceptionStateEncryptedWithoutRollover } from \"../protocol/MessageReceptionState.js\";\nimport { StatusCode, StatusResponseError } from \"../protocol/interaction/StatusCode.js\";\nimport { SubscriptionHandler } from \"../protocol/interaction/SubscriptionHandler.js\";\nimport { ByteArray, Endian } from \"../util/ByteArray.js\";\nimport { DataWriter } from \"../util/DataWriter.js\";\nimport { Session, SessionParameterOptions } from \"./Session.js\";\n\nconst logger = Logger.get(\"SecureSession\");\n\nconst SESSION_KEYS_INFO = ByteArray.fromString(\"SessionKeys\");\nconst SESSION_RESUMPTION_KEYS_INFO = ByteArray.fromString(\"SessionResumptionKeys\");\n\nexport class NoAssociatedFabricError extends StatusResponseError {\n constructor(message: string) {\n super(message, StatusCode.UnsupportedAccess);\n }\n}\n\nexport class SecureSession<T> extends Session<T> {\n readonly #subscriptions = new Array<SubscriptionHandler>();\n #closingAfterExchangeFinished = false;\n #sendCloseMessageWhenClosing = true;\n readonly #context: T;\n readonly #id: number;\n #fabric: Fabric | undefined;\n readonly #peerNodeId: NodeId;\n readonly #peerSessionId: number;\n readonly #decryptKey: ByteArray;\n readonly #encryptKey: ByteArray;\n readonly #attestationKey: ByteArray;\n readonly #subscriptionChangedCallback: () => void;\n #caseAuthenticatedTags: CaseAuthenticatedTag[];\n\n static async create<T>(args: {\n context: T;\n id: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n sharedSecret: ByteArray;\n salt: ByteArray;\n isInitiator: boolean;\n isResumption: boolean;\n closeCallback: () => Promise<void>;\n subscriptionChangedCallback?: () => void;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n }) {\n const {\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n closeCallback,\n sessionParameters,\n caseAuthenticatedTags,\n subscriptionChangedCallback,\n } = args;\n const keys = await Crypto.hkdf(\n sharedSecret,\n salt,\n isResumption ? SESSION_RESUMPTION_KEYS_INFO : SESSION_KEYS_INFO,\n CRYPTO_SYMMETRIC_KEY_LENGTH * 3,\n );\n const decryptKey = isInitiator ? keys.slice(16, 32) : keys.slice(0, 16);\n const encryptKey = isInitiator ? keys.slice(0, 16) : keys.slice(16, 32);\n const attestationKey = keys.slice(32, 48);\n return new SecureSession({\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n decryptKey,\n encryptKey,\n attestationKey,\n closeCallback,\n subscriptionChangedCallback,\n sessionParameters,\n isInitiator,\n caseAuthenticatedTags,\n });\n }\n\n constructor(args: {\n context: T;\n id: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n decryptKey: ByteArray;\n encryptKey: ByteArray;\n attestationKey: ByteArray;\n closeCallback: () => Promise<void>;\n subscriptionChangedCallback?: () => void;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n isInitiator: boolean;\n }) {\n super({\n ...args,\n setActiveTimestamp: true, // We always set the active timestamp for Secure sessions\n // Can be changed to a PersistedMessageCounter if we implement session storage\n messageCounter: new MessageCounter(() => {\n // Secure Session Message Counter\n // Expire/End the session before the counter rolls over\n this.end(true, true).catch(error => logger.error(`Error while closing session: ${error}`));\n }),\n messageReceptionState: new MessageReceptionStateEncryptedWithoutRollover(),\n });\n const {\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n decryptKey,\n encryptKey,\n attestationKey,\n subscriptionChangedCallback = () => {},\n caseAuthenticatedTags,\n } = args;\n\n this.#context = context;\n this.#id = id;\n this.#fabric = fabric;\n this.#peerNodeId = peerNodeId;\n this.#peerSessionId = peerSessionId;\n this.#decryptKey = decryptKey;\n this.#encryptKey = encryptKey;\n this.#attestationKey = attestationKey;\n this.#subscriptionChangedCallback = subscriptionChangedCallback;\n this.#caseAuthenticatedTags = caseAuthenticatedTags ?? fabric?.caseAuthenticatedTags ?? [];\n\n fabric?.addSession(this);\n\n logger.debug(\n `Created secure ${this.isPase ? \"PASE\" : \"CASE\"} session for fabric index ${fabric?.fabricIndex}`,\n this.name,\n Diagnostic.dict({\n idleIntervalMs: this.idleIntervalMs,\n activeIntervalMs: this.activeIntervalMs,\n activeThresholdMs: this.activeThresholdMs,\n }),\n );\n }\n\n get caseAuthenticatedTags() {\n return this.#caseAuthenticatedTags;\n }\n\n get closingAfterExchangeFinished() {\n return this.#closingAfterExchangeFinished;\n }\n\n get sendCloseMessageWhenClosing() {\n return this.#sendCloseMessageWhenClosing;\n }\n\n get isSecure(): boolean {\n return true;\n }\n\n get isPase(): boolean {\n return this.#peerNodeId === NodeId.UNSPECIFIED_NODE_ID;\n }\n\n async close(closeAfterExchangeFinished?: boolean) {\n if (closeAfterExchangeFinished === undefined) {\n closeAfterExchangeFinished = this.isPeerActive(); // We delay session close if the peer is actively communicating with us\n }\n await this.end(true, closeAfterExchangeFinished);\n }\n\n decode({ header, applicationPayload, messageExtension }: DecodedPacket, aad: ByteArray): DecodedMessage {\n if (header.hasMessageExtensions) {\n logger.info(`Message extensions are not supported. Ignoring ${messageExtension?.toHex()}`);\n }\n const nonce = this.generateNonce(header.securityFlags, header.messageId, this.#peerNodeId);\n const message = MessageCodec.decodePayload({\n header,\n applicationPayload: Crypto.decrypt(this.#decryptKey, applicationPayload, nonce, aad),\n });\n\n if (message.payloadHeader.hasSecuredExtension) {\n logger.info(`Secured extensions are not supported. Ignoring ${message.securityExtension?.toHex()}`);\n }\n\n return message;\n }\n\n encode(message: Message): Packet {\n message.packetHeader.sessionId = this.#peerSessionId;\n const { header, applicationPayload } = MessageCodec.encodePayload(message);\n const headerBytes = MessageCodec.encodePacketHeader(message.packetHeader);\n const securityFlags = headerBytes[3];\n const sessionNodeId = this.isPase\n ? NodeId.UNSPECIFIED_NODE_ID\n : this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;\n const nonce = this.generateNonce(securityFlags, header.messageId, sessionNodeId);\n return { header, applicationPayload: Crypto.encrypt(this.#encryptKey, applicationPayload, nonce, headerBytes) };\n }\n\n getAttestationChallengeKey(): ByteArray {\n return this.#attestationKey;\n }\n\n get fabric() {\n return this.#fabric;\n }\n\n addAssociatedFabric(fabric: Fabric) {\n if (this.#fabric !== undefined) {\n throw new MatterFlowError(\"Session already has an associated Fabric. Cannot change this.\");\n }\n this.#fabric = fabric;\n this.#caseAuthenticatedTags = fabric.caseAuthenticatedTags;\n }\n\n get id() {\n return this.#id;\n }\n\n get name() {\n return `secure/${this.#id}`;\n }\n\n get context() {\n return this.#context;\n }\n\n get peerSessionId(): number {\n return this.#peerSessionId;\n }\n\n get nodeId() {\n return this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;\n }\n\n get peerNodeId() {\n return this.#peerNodeId;\n }\n\n get numberOfActiveSubscriptions() {\n return this.#subscriptions.length;\n }\n\n get associatedFabric(): Fabric {\n if (this.#fabric === undefined) {\n throw new NoAssociatedFabricError(\n `${this.isPase ? \"PASE \" : \"\"}Session needs to have an associated Fabric for fabric sensitive data handling.`,\n );\n }\n return this.#fabric;\n }\n\n addSubscription(subscription: SubscriptionHandler) {\n this.#subscriptions.push(subscription);\n logger.debug(`Added subscription ${subscription.subscriptionId} to ${this.name}`);\n this.#subscriptionChangedCallback();\n }\n\n removeSubscription(subscriptionId: number) {\n const index = this.#subscriptions.findIndex(subscription => subscription.subscriptionId === subscriptionId);\n if (index !== -1) {\n this.#subscriptions.splice(index, 1);\n logger.debug(`Removed subscription ${subscriptionId} from ${this.name}`);\n this.#subscriptionChangedCallback();\n }\n }\n\n async clearSubscriptions(flushSubscriptions = false) {\n for (const subscription of this.#subscriptions) {\n await subscription.cancel(flushSubscriptions);\n }\n this.#subscriptions.length = 0;\n }\n\n /** Ends a session. Outstanding subscription data will be flushed before the session is destroyed. */\n async end(sendClose: boolean, closeAfterExchangeFinished = false) {\n await this.clearSubscriptions(true);\n await this.destroy(sendClose, closeAfterExchangeFinished);\n }\n\n /** Destroys a session. Outstanding subscription data will be discarded. */\n async destroy(sendClose = false, closeAfterExchangeFinished = true) {\n await this.clearSubscriptions(false);\n this.#fabric?.removeSession(this);\n if (!sendClose) {\n this.#sendCloseMessageWhenClosing = false;\n }\n\n if (closeAfterExchangeFinished) {\n logger.info(`Register Session ${this.name} to send a close when exchange is ended.`);\n this.#closingAfterExchangeFinished = true;\n } else {\n await this.closeCallback();\n }\n }\n\n private generateNonce(securityFlags: number, messageId: number, nodeId: NodeId) {\n const writer = new DataWriter(Endian.Little);\n writer.writeUInt8(securityFlags);\n writer.writeUInt32(messageId);\n writer.writeUInt64(nodeId);\n return writer.toByteArray();\n }\n}\n\nexport function assertSecureSession<T>(session: Session<T>, errorText?: string): asserts session is SecureSession<T> {\n if (!session.isSecure) {\n throw new MatterFlowError(errorText ?? \"Insecure session in secure context\");\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { DecodedMessage, DecodedPacket, Message, MessageCodec, Packet } from \"../codec/MessageCodec.js\";\nimport { MatterFlowError } from \"../common/MatterError.js\";\nimport { CRYPTO_SYMMETRIC_KEY_LENGTH, Crypto } from \"../crypto/Crypto.js\";\nimport { CaseAuthenticatedTag } from \"../datatype/CaseAuthenticatedTag.js\";\nimport { NodeId } from \"../datatype/NodeId.js\";\nimport { Fabric } from \"../fabric/Fabric.js\";\nimport { Diagnostic } from \"../log/Diagnostic.js\";\nimport { Logger } from \"../log/Logger.js\";\nimport { MessageCounter } from \"../protocol/MessageCounter.js\";\nimport { MessageReceptionStateEncryptedWithoutRollover } from \"../protocol/MessageReceptionState.js\";\nimport { StatusCode, StatusResponseError } from \"../protocol/interaction/StatusCode.js\";\nimport { SubscriptionHandler } from \"../protocol/interaction/SubscriptionHandler.js\";\nimport { ByteArray, Endian } from \"../util/ByteArray.js\";\nimport { DataWriter } from \"../util/DataWriter.js\";\nimport { Session, SessionParameterOptions } from \"./Session.js\";\n\nconst logger = Logger.get(\"SecureSession\");\n\nconst SESSION_KEYS_INFO = ByteArray.fromString(\"SessionKeys\");\nconst SESSION_RESUMPTION_KEYS_INFO = ByteArray.fromString(\"SessionResumptionKeys\");\n\nexport class NoAssociatedFabricError extends StatusResponseError {\n constructor(message: string) {\n super(message, StatusCode.UnsupportedAccess);\n }\n}\n\nexport class SecureSession<T> extends Session<T> {\n readonly #subscriptions = new Array<SubscriptionHandler>();\n #closingAfterExchangeFinished = false;\n #sendCloseMessageWhenClosing = true;\n readonly #context: T;\n readonly #id: number;\n #fabric: Fabric | undefined;\n readonly #peerNodeId: NodeId;\n readonly #peerSessionId: number;\n readonly #decryptKey: ByteArray;\n readonly #encryptKey: ByteArray;\n readonly #attestationKey: ByteArray;\n readonly #subscriptionChangedCallback: () => void;\n #caseAuthenticatedTags: CaseAuthenticatedTag[];\n\n static async create<T>(args: {\n context: T;\n id: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n sharedSecret: ByteArray;\n salt: ByteArray;\n isInitiator: boolean;\n isResumption: boolean;\n closeCallback: () => Promise<void>;\n subscriptionChangedCallback?: () => void;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n }) {\n const {\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n closeCallback,\n sessionParameters,\n caseAuthenticatedTags,\n subscriptionChangedCallback,\n } = args;\n const keys = await Crypto.hkdf(\n sharedSecret,\n salt,\n isResumption ? SESSION_RESUMPTION_KEYS_INFO : SESSION_KEYS_INFO,\n CRYPTO_SYMMETRIC_KEY_LENGTH * 3,\n );\n const decryptKey = isInitiator ? keys.slice(16, 32) : keys.slice(0, 16);\n const encryptKey = isInitiator ? keys.slice(0, 16) : keys.slice(16, 32);\n const attestationKey = keys.slice(32, 48);\n return new SecureSession({\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n decryptKey,\n encryptKey,\n attestationKey,\n closeCallback,\n subscriptionChangedCallback,\n sessionParameters,\n isInitiator,\n caseAuthenticatedTags,\n });\n }\n\n constructor(args: {\n context: T;\n id: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n decryptKey: ByteArray;\n encryptKey: ByteArray;\n attestationKey: ByteArray;\n closeCallback: () => Promise<void>;\n subscriptionChangedCallback?: () => void;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n isInitiator: boolean;\n }) {\n super({\n ...args,\n setActiveTimestamp: true, // We always set the active timestamp for Secure sessions\n // Can be changed to a PersistedMessageCounter if we implement session storage\n messageCounter: new MessageCounter(() => {\n // Secure Session Message Counter\n // Expire/End the session before the counter rolls over\n this.end(true, true).catch(error => logger.error(`Error while closing session: ${error}`));\n }),\n messageReceptionState: new MessageReceptionStateEncryptedWithoutRollover(),\n });\n const {\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n decryptKey,\n encryptKey,\n attestationKey,\n subscriptionChangedCallback = () => {},\n caseAuthenticatedTags,\n } = args;\n\n this.#context = context;\n this.#id = id;\n this.#fabric = fabric;\n this.#peerNodeId = peerNodeId;\n this.#peerSessionId = peerSessionId;\n this.#decryptKey = decryptKey;\n this.#encryptKey = encryptKey;\n this.#attestationKey = attestationKey;\n this.#subscriptionChangedCallback = subscriptionChangedCallback;\n this.#caseAuthenticatedTags = caseAuthenticatedTags ?? fabric?.caseAuthenticatedTags ?? [];\n\n fabric?.addSession(this);\n\n logger.debug(\n `Created secure ${this.isPase ? \"PASE\" : \"CASE\"} session for fabric index ${fabric?.fabricIndex}`,\n this.name,\n Diagnostic.dict({\n idleIntervalMs: this.idleIntervalMs,\n activeIntervalMs: this.activeIntervalMs,\n activeThresholdMs: this.activeThresholdMs,\n }),\n );\n }\n\n get caseAuthenticatedTags() {\n return this.#caseAuthenticatedTags;\n }\n\n get closingAfterExchangeFinished() {\n return this.#closingAfterExchangeFinished;\n }\n\n get sendCloseMessageWhenClosing() {\n return this.#sendCloseMessageWhenClosing;\n }\n\n get isSecure(): boolean {\n return true;\n }\n\n get isPase(): boolean {\n return this.#peerNodeId === NodeId.UNSPECIFIED_NODE_ID;\n }\n\n async close(closeAfterExchangeFinished?: boolean) {\n if (closeAfterExchangeFinished === undefined) {\n closeAfterExchangeFinished = this.isPeerActive(); // We delay session close if the peer is actively communicating with us\n }\n await this.end(true, closeAfterExchangeFinished);\n }\n\n decode({ header, applicationPayload, messageExtension }: DecodedPacket, aad: ByteArray): DecodedMessage {\n if (header.hasMessageExtensions) {\n logger.info(`Message extensions are not supported. Ignoring ${messageExtension?.toHex()}`);\n }\n const nonce = this.generateNonce(header.securityFlags, header.messageId, this.#peerNodeId);\n const message = MessageCodec.decodePayload({\n header,\n applicationPayload: Crypto.decrypt(this.#decryptKey, applicationPayload, nonce, aad),\n });\n\n if (message.payloadHeader.hasSecuredExtension) {\n logger.info(`Secured extensions are not supported. Ignoring ${message.securityExtension?.toHex()}`);\n }\n\n return message;\n }\n\n encode(message: Message): Packet {\n message.packetHeader.sessionId = this.#peerSessionId;\n const { header, applicationPayload } = MessageCodec.encodePayload(message);\n const headerBytes = MessageCodec.encodePacketHeader(message.packetHeader);\n const securityFlags = headerBytes[3];\n const sessionNodeId = this.isPase\n ? NodeId.UNSPECIFIED_NODE_ID\n : this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;\n const nonce = this.generateNonce(securityFlags, header.messageId, sessionNodeId);\n return { header, applicationPayload: Crypto.encrypt(this.#encryptKey, applicationPayload, nonce, headerBytes) };\n }\n\n getAttestationChallengeKey(): ByteArray {\n return this.#attestationKey;\n }\n\n get fabric() {\n return this.#fabric;\n }\n\n addAssociatedFabric(fabric: Fabric) {\n if (this.#fabric !== undefined) {\n throw new MatterFlowError(\"Session already has an associated Fabric. Cannot change this.\");\n }\n this.#fabric = fabric;\n this.#caseAuthenticatedTags = fabric.caseAuthenticatedTags;\n }\n\n get id() {\n return this.#id;\n }\n\n get name() {\n return `secure/${this.#id}`;\n }\n\n get context() {\n return this.#context;\n }\n\n get peerSessionId(): number {\n return this.#peerSessionId;\n }\n\n get nodeId() {\n return this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;\n }\n\n get peerNodeId() {\n return this.#peerNodeId;\n }\n\n get numberOfActiveSubscriptions() {\n return this.#subscriptions.length;\n }\n\n get associatedFabric(): Fabric {\n if (this.#fabric === undefined) {\n throw new NoAssociatedFabricError(\n `${this.isPase ? \"PASE \" : \"\"}Session needs to have an associated Fabric for fabric sensitive data handling.`,\n );\n }\n return this.#fabric;\n }\n\n addSubscription(subscription: SubscriptionHandler) {\n this.#subscriptions.push(subscription);\n logger.debug(`Added subscription ${subscription.subscriptionId} to ${this.name}`);\n this.#subscriptionChangedCallback();\n }\n\n removeSubscription(subscriptionId: number) {\n const index = this.#subscriptions.findIndex(subscription => subscription.subscriptionId === subscriptionId);\n if (index !== -1) {\n this.#subscriptions.splice(index, 1);\n logger.debug(`Removed subscription ${subscriptionId} from ${this.name}`);\n this.#subscriptionChangedCallback();\n }\n }\n\n async clearSubscriptions(flushSubscriptions = false) {\n const subscriptions = [...this.#subscriptions]; // get all values because subscriptions will remove themselves when cancelled\n for (const subscription of subscriptions) {\n await subscription.cancel(flushSubscriptions);\n }\n this.#subscriptions.length = 0;\n }\n\n /** Ends a session. Outstanding subscription data will be flushed before the session is destroyed. */\n async end(sendClose: boolean, closeAfterExchangeFinished = false) {\n await this.clearSubscriptions(true);\n await this.destroy(sendClose, closeAfterExchangeFinished);\n }\n\n /** Destroys a session. Outstanding subscription data will be discarded. */\n async destroy(sendClose = false, closeAfterExchangeFinished = true) {\n await this.clearSubscriptions(false);\n this.#fabric?.removeSession(this);\n if (!sendClose) {\n this.#sendCloseMessageWhenClosing = false;\n }\n\n if (closeAfterExchangeFinished) {\n logger.info(`Register Session ${this.name} to send a close when exchange is ended.`);\n this.#closingAfterExchangeFinished = true;\n } else {\n await this.closeCallback();\n }\n }\n\n private generateNonce(securityFlags: number, messageId: number, nodeId: NodeId) {\n const writer = new DataWriter(Endian.Little);\n writer.writeUInt8(securityFlags);\n writer.writeUInt32(messageId);\n writer.writeUInt64(nodeId);\n return writer.toByteArray();\n }\n}\n\nexport function assertSecureSession<T>(session: Session<T>, errorText?: string): asserts session is SecureSession<T> {\n if (!session.isSecure) {\n throw new MatterFlowError(errorText ?? \"Insecure session in secure context\");\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -72,6 +72,7 @@ export declare class SessionManager<ContextT> {
|
|
|
72
72
|
lastActiveTimestamp: number | undefined;
|
|
73
73
|
numberOfActiveSubscriptions: number;
|
|
74
74
|
}[];
|
|
75
|
+
clearSubscriptionsForNode(nodeId: NodeId, flushSubscriptions?: boolean): Promise<void>;
|
|
75
76
|
close(): Promise<void>;
|
|
76
77
|
}
|
|
77
78
|
//# sourceMappingURL=SessionManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../../src/session/SessionManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAI1E,eAAO,MAAM,2BAA2B,IAAS,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC7B,YAAY,EAAE,SAAS,CAAC;IACxB,YAAY,EAAE,SAAS,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;CAClD;AAgBD,qBAAa,cAAc,CAAC,QAAQ;;IAY5B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,QAAQ,EAClC,cAAc,EAAE,cAAc;IAKlC,IAAI,oBAAoB,yDAEvB;IAED,IAAI,aAAa,yDAEhB;IAED,IAAI,aAAa,8DAEhB;IAED,qBAAqB,CAAC,OAAO,EAAE;QAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;KACzB;IA4BK,mBAAmB,CAAC,IAAI,EAAE;QAC5B,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,SAAS,CAAC;QACxB,IAAI,EAAE,SAAS,CAAC;QAChB,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,EAAE,OAAO,CAAC;QACtB,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;KAClD;IA0CD,aAAa,CAAC,SAAS,EAAE,MAAM;IAOzB,sBAAsB,CAAC,UAAU,EAAE,MAAM;IAK/C,yBAAyB;IAanB,yBAAyB;IAkB/B,UAAU,CAAC,SAAS,EAAE,MAAM;IAI5B,cAAc;IAMd,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAS1C,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,UAAQ;IAUhE,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM;IAOxC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;IASxD,wBAAwB,CAAC,YAAY,EAAE,SAAS;IAIhD,4BAA4B,CAAC,MAAM,EAAE,MAAM;IAIrC,oBAAoB,CAAC,gBAAgB,EAAE,gBAAgB;IAKvD,gCAAgC,CAAC,MAAM,EAAE,MAAM;IAS/C,sBAAsB;IAqBtB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE;IAkCvC,2BAA2B;;;;;;;;;;;IAgBrB,KAAK;CAWd"}
|
|
1
|
+
{"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../../src/session/SessionManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAI1E,eAAO,MAAM,2BAA2B,IAAS,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC7B,YAAY,EAAE,SAAS,CAAC;IACxB,YAAY,EAAE,SAAS,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;CAClD;AAgBD,qBAAa,cAAc,CAAC,QAAQ;;IAY5B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,QAAQ,EAClC,cAAc,EAAE,cAAc;IAKlC,IAAI,oBAAoB,yDAEvB;IAED,IAAI,aAAa,yDAEhB;IAED,IAAI,aAAa,8DAEhB;IAED,qBAAqB,CAAC,OAAO,EAAE;QAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;KACzB;IA4BK,mBAAmB,CAAC,IAAI,EAAE;QAC5B,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,SAAS,CAAC;QACxB,IAAI,EAAE,SAAS,CAAC;QAChB,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,EAAE,OAAO,CAAC;QACtB,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;KAClD;IA0CD,aAAa,CAAC,SAAS,EAAE,MAAM;IAOzB,sBAAsB,CAAC,UAAU,EAAE,MAAM;IAK/C,yBAAyB;IAanB,yBAAyB;IAkB/B,UAAU,CAAC,SAAS,EAAE,MAAM;IAI5B,cAAc;IAMd,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAS1C,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,UAAQ;IAUhE,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM;IAOxC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;IASxD,wBAAwB,CAAC,YAAY,EAAE,SAAS;IAIhD,4BAA4B,CAAC,MAAM,EAAE,MAAM;IAIrC,oBAAoB,CAAC,gBAAgB,EAAE,gBAAgB;IAKvD,gCAAgC,CAAC,MAAM,EAAE,MAAM;IAS/C,sBAAsB;IAqBtB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE;IAkCvC,2BAA2B;;;;;;;;;;;IAgBrB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,OAAO;IAQtE,KAAK;CAWd"}
|
|
@@ -275,6 +275,13 @@ class SessionManager {
|
|
|
275
275
|
numberOfActiveSubscriptions: session instanceof import_SecureSession.SecureSession ? session.numberOfActiveSubscriptions : 0
|
|
276
276
|
}));
|
|
277
277
|
}
|
|
278
|
+
async clearSubscriptionsForNode(nodeId, flushSubscriptions) {
|
|
279
|
+
for (const session of this.#sessions) {
|
|
280
|
+
if (session.peerNodeId === nodeId) {
|
|
281
|
+
await session.clearSubscriptions(flushSubscriptions);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
278
285
|
async close() {
|
|
279
286
|
await this.storeResumptionRecords();
|
|
280
287
|
for (const session of this.#sessions) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/session/SessionManager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MatterFlowError } from \"../common/MatterError.js\";\nimport { Crypto } from \"../crypto/Crypto.js\";\nimport { CaseAuthenticatedTag } from \"../datatype/CaseAuthenticatedTag.js\";\nimport { FabricId } from \"../datatype/FabricId.js\";\nimport { NodeId } from \"../datatype/NodeId.js\";\nimport { Fabric } from \"../fabric/Fabric.js\";\nimport { Logger } from \"../log/Logger.js\";\nimport { MessageCounter } from \"../protocol/MessageCounter.js\";\nimport { StorageContext } from \"../storage/StorageContext.js\";\nimport { ByteArray } from \"../util/ByteArray.js\";\nimport { AsyncObservable, Observable } from \"../util/Observable.js\";\nimport { BasicSet } from \"../util/Set.js\";\nimport { InsecureSession } from \"./InsecureSession.js\";\nimport { SecureSession } from \"./SecureSession.js\";\nimport { SessionParameterOptions, SessionParameters } from \"./Session.js\";\n\nconst logger = Logger.get(\"SessionManager\");\n\nexport const UNICAST_UNSECURE_SESSION_ID = 0x0000;\n\nexport interface ResumptionRecord {\n sharedSecret: ByteArray;\n resumptionId: ByteArray;\n fabric: Fabric;\n peerNodeId: NodeId;\n sessionParameters: SessionParameters;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n}\n\ntype ResumptionStorageRecord = {\n nodeId: NodeId;\n sharedSecret: Uint8Array;\n resumptionId: Uint8Array;\n fabricId: FabricId;\n peerNodeId: NodeId;\n sessionParameters: {\n idleIntervalMs: number;\n activeIntervalMs: number;\n activeThresholdMs: number;\n };\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n};\n\nexport class SessionManager<ContextT> {\n readonly #insecureSessions = new Map<NodeId, InsecureSession<ContextT>>();\n readonly #sessions = new BasicSet<SecureSession<ContextT>>();\n #nextSessionId = Crypto.getRandomUInt16();\n #resumptionRecords = new Map<NodeId, ResumptionRecord>();\n readonly #sessionStorage: StorageContext;\n readonly #globalUnencryptedMessageCounter = new MessageCounter();\n readonly #subscriptionsChanged = new Observable<[session: SecureSession<ContextT>]>();\n readonly #sessionOpened = new Observable<[session: SecureSession<ContextT>]>();\n readonly #sessionClosed = new AsyncObservable<[session: SecureSession<ContextT>], void>();\n\n constructor(\n private readonly context: ContextT,\n sessionStorage: StorageContext,\n ) {\n this.#sessionStorage = sessionStorage;\n }\n\n get subscriptionsChanged() {\n return this.#subscriptionsChanged;\n }\n\n get sessionOpened() {\n return this.#sessionOpened;\n }\n\n get sessionClosed() {\n return this.#sessionClosed;\n }\n\n createUnsecureSession(options: {\n initiatorNodeId?: NodeId;\n sessionParameters?: SessionParameterOptions;\n isInitiator?: boolean;\n }) {\n const { initiatorNodeId, sessionParameters, isInitiator } = options;\n if (initiatorNodeId !== undefined) {\n if (this.#insecureSessions.has(initiatorNodeId)) {\n throw new MatterFlowError(`UnsecureSession with NodeId ${initiatorNodeId} already exists.`);\n }\n }\n while (true) {\n const session = new InsecureSession({\n context: this.context,\n messageCounter: this.#globalUnencryptedMessageCounter,\n closeCallback: async () => {\n logger.info(`End insecure session ${session.name}`);\n this.#insecureSessions.delete(session.nodeId);\n },\n initiatorNodeId,\n sessionParameters,\n isInitiator: isInitiator ?? false,\n });\n\n const ephermalNodeId = session.nodeId;\n if (this.#insecureSessions.has(ephermalNodeId)) continue;\n\n this.#insecureSessions.set(ephermalNodeId, session);\n return session;\n }\n }\n\n async createSecureSession(args: {\n sessionId: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n sharedSecret: ByteArray;\n salt: ByteArray;\n isInitiator: boolean;\n isResumption: boolean;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n }) {\n const {\n sessionId,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n sessionParameters,\n caseAuthenticatedTags,\n } = args;\n const session = await SecureSession.create({\n context: this.context,\n id: sessionId,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n closeCallback: async () => {\n logger.info(`End ${session.isPase ? \"PASE\" : \"CASE\"} session ${session.name}`);\n this.#sessions.delete(session);\n await this.#sessionClosed.emit(session);\n },\n sessionParameters,\n caseAuthenticatedTags,\n subscriptionChangedCallback: () => {\n this.#subscriptionsChanged.emit(session);\n },\n });\n\n this.#sessions.add(session);\n this.#sessionOpened.emit(session);\n\n // TODO: Add a maximum of sessions and respect/close the \"least recently used\" session. See Core Specs 4.10.1.1\n return session;\n }\n\n removeSession(sessionId: number) {\n const session = this.getSession(sessionId);\n if (session !== undefined) {\n this.#sessions.delete(session);\n }\n }\n\n async removeResumptionRecord(peerNodeId: NodeId) {\n this.#resumptionRecords.delete(peerNodeId);\n await this.storeResumptionRecords();\n }\n\n findOldestInactiveSession() {\n let oldestSession: SecureSession<ContextT> | undefined = undefined;\n for (const session of this.#sessions) {\n if (!oldestSession || session.activeTimestamp < oldestSession.activeTimestamp) {\n oldestSession = session;\n }\n }\n if (oldestSession === undefined) {\n throw new MatterFlowError(\"No session found to close and all session ids are taken.\");\n }\n return oldestSession;\n }\n\n async getNextAvailableSessionId() {\n for (let i = 0; i < 0xffff; i++) {\n const id = this.#nextSessionId;\n this.#nextSessionId = (this.#nextSessionId + 1) & 0xffff;\n if (this.#nextSessionId === 0) this.#nextSessionId++;\n\n if (this.getSession(id) === undefined) {\n return id;\n }\n }\n\n // All session ids are taken, search for the oldest unused session, and close it and re-use its ID\n const oldestSession = this.findOldestInactiveSession();\n await oldestSession.end(true, false);\n this.#nextSessionId = oldestSession.id;\n return this.#nextSessionId++;\n }\n\n getSession(sessionId: number) {\n return this.#sessions.get(\"id\", sessionId);\n }\n\n getPaseSession() {\n return [...this.#sessions].find(\n session => session.isSecure && session.isPase && !session.closingAfterExchangeFinished,\n ) as SecureSession<ContextT>;\n }\n\n getSessionForNode(fabric: Fabric, nodeId: NodeId) {\n //TODO: It can have multiple sessions for one node ...\n return [...this.#sessions].find(session => {\n if (!session.isSecure) return false;\n const secureSession = session as SecureSession<any>;\n return secureSession.fabric?.fabricId === fabric.fabricId && secureSession.peerNodeId === nodeId;\n });\n }\n\n async removeAllSessionsForNode(nodeId: NodeId, sendClose = false) {\n for (const session of this.#sessions) {\n if (!session.isSecure) continue;\n const secureSession = session as SecureSession<any>;\n if (secureSession.peerNodeId === nodeId) {\n await secureSession.destroy(sendClose, false);\n }\n }\n }\n\n getUnsecureSession(sourceNodeId?: NodeId) {\n if (sourceNodeId === undefined) {\n return this.#insecureSessions.get(NodeId.UNSPECIFIED_NODE_ID);\n }\n return this.#insecureSessions.get(sourceNodeId);\n }\n\n findGroupSession(groupId: number, groupSessionId: number) {\n // Use groupsession id to find the key ??!!\n // The Group Session ID MAY help receiving nodes efficiently locate the Operational Group Key used to encrypt an incoming groupcast message. It SHALL NOT be used as the sole means to locate the asso\u00AD ciated Operational Group Key, since it MAY collide within the fabric. Instead, the Group Session ID provides receiving nodes a means to identify Operational Group Key candidates without the need to first attempt to decrypt groupcast messages using all available keys.\n // On receipt of a message of Group Session Type, all valid, installed, operational group key candidates referenced by the given Group Session ID SHALL be attempted until authentication is passed or there are no more operational group keys to try. This is done because the same Group Session ID might arise from different keys. The chance of a Group Session ID collision is 2-16 but the chance of both a Group Session ID collision and the message MIC matching two different operational group keys is 2-80.\n\n // TODO\n throw new Error(`Not implemented ${groupId} ${groupSessionId}`);\n }\n\n findResumptionRecordById(resumptionId: ByteArray) {\n return [...this.#resumptionRecords.values()].find(record => record.resumptionId.equals(resumptionId));\n }\n\n findResumptionRecordByNodeId(nodeId: NodeId) {\n return this.#resumptionRecords.get(nodeId);\n }\n\n async saveResumptionRecord(resumptionRecord: ResumptionRecord) {\n this.#resumptionRecords.set(resumptionRecord.peerNodeId, resumptionRecord);\n await this.storeResumptionRecords();\n }\n\n async updateFabricForResumptionRecords(fabric: Fabric) {\n const record = this.#resumptionRecords.get(fabric.rootNodeId);\n if (record === undefined) {\n throw new MatterFlowError(\"Resumption record not found. Should never happen.\");\n }\n this.#resumptionRecords.set(fabric.rootNodeId, { ...record, fabric });\n await this.storeResumptionRecords();\n }\n\n async storeResumptionRecords() {\n await this.#sessionStorage.set(\n \"resumptionRecords\",\n [...this.#resumptionRecords].map(\n ([\n nodeId,\n { sharedSecret, resumptionId, peerNodeId, fabric, sessionParameters, caseAuthenticatedTags },\n ]) =>\n ({\n nodeId,\n sharedSecret,\n resumptionId,\n fabricId: fabric.fabricId,\n peerNodeId: peerNodeId,\n sessionParameters,\n caseAuthenticatedTags,\n }) as ResumptionStorageRecord,\n ),\n );\n }\n\n async initFromStorage(fabrics: Fabric[]) {\n const storedResumptionRecords = await this.#sessionStorage.get<ResumptionStorageRecord[]>(\n \"resumptionRecords\",\n [],\n );\n\n storedResumptionRecords.forEach(\n ({\n nodeId,\n sharedSecret,\n resumptionId,\n fabricId,\n peerNodeId,\n sessionParameters,\n caseAuthenticatedTags,\n }) => {\n logger.info(\"restoring resumption record for node\", nodeId);\n const fabric = fabrics.find(fabric => fabric.fabricId === fabricId);\n if (!fabric) {\n logger.error(\"fabric not found for resumption record\", fabricId);\n return;\n }\n this.#resumptionRecords.set(nodeId, {\n sharedSecret,\n resumptionId,\n fabric,\n peerNodeId,\n sessionParameters,\n caseAuthenticatedTags,\n });\n },\n );\n }\n\n getActiveSessionInformation() {\n return [...this.#sessions]\n .filter(session => session.isSecure && !session.isPase)\n .map(session => ({\n name: session.name,\n nodeId: session.nodeId,\n peerNodeId: session.peerNodeId,\n fabric: session instanceof SecureSession ? session.fabric?.externalInformation : undefined,\n isPeerActive: session.isPeerActive(),\n secure: session.isSecure,\n lastInteractionTimestamp: session instanceof SecureSession ? session.timestamp : undefined,\n lastActiveTimestamp: session instanceof SecureSession ? session.activeTimestamp : undefined,\n numberOfActiveSubscriptions: session instanceof SecureSession ? session.numberOfActiveSubscriptions : 0,\n }));\n }\n\n async close() {\n await this.storeResumptionRecords();\n for (const session of this.#sessions) {\n await session?.end(false);\n this.#sessions.delete(session);\n }\n for (const session of this.#insecureSessions.values()) {\n await session?.end();\n this.#insecureSessions.delete(session.nodeId);\n }\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,yBAAgC;AAChC,oBAAuB;AAGvB,oBAAuB;AAEvB,oBAAuB;AACvB,4BAA+B;AAG/B,wBAA4C;AAC5C,iBAAyB;AACzB,6BAAgC;AAChC,2BAA8B;AAnB9B;AAAA;AAAA;AAAA;AAAA;AAsBA,MAAM,SAAS,qBAAO,IAAI,gBAAgB;AAEnC,MAAM,8BAA8B;AAyBpC,MAAM,eAAyB;AAAA,EAWlC,YACqB,SACjB,gBACF;AAFmB;AAGjB,SAAK,kBAAkB;AAAA,EAC3B;AAAA,EAfS,oBAAoB,oBAAI,IAAuC;AAAA,EAC/D,YAAY,IAAI,oBAAkC;AAAA,EAC3D,iBAAiB,qBAAO,gBAAgB;AAAA,EACxC,qBAAqB,oBAAI,IAA8B;AAAA,EAC9C;AAAA,EACA,mCAAmC,IAAI,qCAAe;AAAA,EACtD,wBAAwB,IAAI,6BAA+C;AAAA,EAC3E,iBAAiB,IAAI,6BAA+C;AAAA,EACpE,iBAAiB,IAAI,kCAA0D;AAAA,EASxF,IAAI,uBAAuB;AACvB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,gBAAgB;AAChB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,gBAAgB;AAChB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,sBAAsB,SAInB;AACC,UAAM,EAAE,iBAAiB,mBAAmB,YAAY,IAAI;AAC5D,QAAI,oBAAoB,QAAW;AAC/B,UAAI,KAAK,kBAAkB,IAAI,eAAe,GAAG;AAC7C,cAAM,IAAI,mCAAgB,+BAA+B,eAAe,kBAAkB;AAAA,MAC9F;AAAA,IACJ;AACA,WAAO,MAAM;AACT,YAAM,UAAU,IAAI,uCAAgB;AAAA,QAChC,SAAS,KAAK;AAAA,QACd,gBAAgB,KAAK;AAAA,QACrB,eAAe,YAAY;AACvB,iBAAO,KAAK,wBAAwB,QAAQ,IAAI,EAAE;AAClD,eAAK,kBAAkB,OAAO,QAAQ,MAAM;AAAA,QAChD;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa,eAAe;AAAA,MAChC,CAAC;AAED,YAAM,iBAAiB,QAAQ;AAC/B,UAAI,KAAK,kBAAkB,IAAI,cAAc,EAAG;AAEhD,WAAK,kBAAkB,IAAI,gBAAgB,OAAO;AAClD,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EAEA,MAAM,oBAAoB,MAWvB;AACC,UAAM;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACJ,IAAI;AACJ,UAAM,UAAU,MAAM,mCAAc,OAAO;AAAA,MACvC,SAAS,KAAK;AAAA,MACd,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe,YAAY;AACvB,eAAO,KAAK,OAAO,QAAQ,SAAS,SAAS,MAAM,YAAY,QAAQ,IAAI,EAAE;AAC7E,aAAK,UAAU,OAAO,OAAO;AAC7B,cAAM,KAAK,eAAe,KAAK,OAAO;AAAA,MAC1C;AAAA,MACA;AAAA,MACA;AAAA,MACA,6BAA6B,MAAM;AAC/B,aAAK,sBAAsB,KAAK,OAAO;AAAA,MAC3C;AAAA,IACJ,CAAC;AAED,SAAK,UAAU,IAAI,OAAO;AAC1B,SAAK,eAAe,KAAK,OAAO;AAGhC,WAAO;AAAA,EACX;AAAA,EAEA,cAAc,WAAmB;AAC7B,UAAM,UAAU,KAAK,WAAW,SAAS;AACzC,QAAI,YAAY,QAAW;AACvB,WAAK,UAAU,OAAO,OAAO;AAAA,IACjC;AAAA,EACJ;AAAA,EAEA,MAAM,uBAAuB,YAAoB;AAC7C,SAAK,mBAAmB,OAAO,UAAU;AACzC,UAAM,KAAK,uBAAuB;AAAA,EACtC;AAAA,EAEA,4BAA4B;AACxB,QAAI,gBAAqD;AACzD,eAAW,WAAW,KAAK,WAAW;AAClC,UAAI,CAAC,iBAAiB,QAAQ,kBAAkB,cAAc,iBAAiB;AAC3E,wBAAgB;AAAA,MACpB;AAAA,IACJ;AACA,QAAI,kBAAkB,QAAW;AAC7B,YAAM,IAAI,mCAAgB,0DAA0D;AAAA,IACxF;AACA,WAAO;AAAA,EACX;AAAA,EAEA,MAAM,4BAA4B;AAC9B,aAAS,IAAI,GAAG,IAAI,OAAQ,KAAK;AAC7B,YAAM,KAAK,KAAK;AAChB,WAAK,iBAAkB,KAAK,iBAAiB,IAAK;AAClD,UAAI,KAAK,mBAAmB,EAAG,MAAK;AAEpC,UAAI,KAAK,WAAW,EAAE,MAAM,QAAW;AACnC,eAAO;AAAA,MACX;AAAA,IACJ;AAGA,UAAM,gBAAgB,KAAK,0BAA0B;AACrD,UAAM,cAAc,IAAI,MAAM,KAAK;AACnC,SAAK,iBAAiB,cAAc;AACpC,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,WAAW,WAAmB;AAC1B,WAAO,KAAK,UAAU,IAAI,MAAM,SAAS;AAAA,EAC7C;AAAA,EAEA,iBAAiB;AACb,WAAO,CAAC,GAAG,KAAK,SAAS,EAAE;AAAA,MACvB,aAAW,QAAQ,YAAY,QAAQ,UAAU,CAAC,QAAQ;AAAA,IAC9D;AAAA,EACJ;AAAA,EAEA,kBAAkB,QAAgB,QAAgB;AAE9C,WAAO,CAAC,GAAG,KAAK,SAAS,EAAE,KAAK,aAAW;AACvC,UAAI,CAAC,QAAQ,SAAU,QAAO;AAC9B,YAAM,gBAAgB;AACtB,aAAO,cAAc,QAAQ,aAAa,OAAO,YAAY,cAAc,eAAe;AAAA,IAC9F,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,yBAAyB,QAAgB,YAAY,OAAO;AAC9D,eAAW,WAAW,KAAK,WAAW;AAClC,UAAI,CAAC,QAAQ,SAAU;AACvB,YAAM,gBAAgB;AACtB,UAAI,cAAc,eAAe,QAAQ;AACrC,cAAM,cAAc,QAAQ,WAAW,KAAK;AAAA,MAChD;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,mBAAmB,cAAuB;AACtC,QAAI,iBAAiB,QAAW;AAC5B,aAAO,KAAK,kBAAkB,IAAI,qBAAO,mBAAmB;AAAA,IAChE;AACA,WAAO,KAAK,kBAAkB,IAAI,YAAY;AAAA,EAClD;AAAA,EAEA,iBAAiB,SAAiB,gBAAwB;AAMtD,UAAM,IAAI,MAAM,mBAAmB,OAAO,IAAI,cAAc,EAAE;AAAA,EAClE;AAAA,EAEA,yBAAyB,cAAyB;AAC9C,WAAO,CAAC,GAAG,KAAK,mBAAmB,OAAO,CAAC,EAAE,KAAK,YAAU,OAAO,aAAa,OAAO,YAAY,CAAC;AAAA,EACxG;AAAA,EAEA,6BAA6B,QAAgB;AACzC,WAAO,KAAK,mBAAmB,IAAI,MAAM;AAAA,EAC7C;AAAA,EAEA,MAAM,qBAAqB,kBAAoC;AAC3D,SAAK,mBAAmB,IAAI,iBAAiB,YAAY,gBAAgB;AACzE,UAAM,KAAK,uBAAuB;AAAA,EACtC;AAAA,EAEA,MAAM,iCAAiC,QAAgB;AACnD,UAAM,SAAS,KAAK,mBAAmB,IAAI,OAAO,UAAU;AAC5D,QAAI,WAAW,QAAW;AACtB,YAAM,IAAI,mCAAgB,mDAAmD;AAAA,IACjF;AACA,SAAK,mBAAmB,IAAI,OAAO,YAAY,EAAE,GAAG,QAAQ,OAAO,CAAC;AACpE,UAAM,KAAK,uBAAuB;AAAA,EACtC;AAAA,EAEA,MAAM,yBAAyB;AAC3B,UAAM,KAAK,gBAAgB;AAAA,MACvB;AAAA,MACA,CAAC,GAAG,KAAK,kBAAkB,EAAE;AAAA,QACzB,CAAC;AAAA,UACG;AAAA,UACA,EAAE,cAAc,cAAc,YAAY,QAAQ,mBAAmB,sBAAsB;AAAA,QAC/F,OACK;AAAA,UACG;AAAA,UACA;AAAA,UACA;AAAA,UACA,UAAU,OAAO;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,QACJ;AAAA,MACR;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,MAAM,gBAAgB,SAAmB;AACrC,UAAM,0BAA0B,MAAM,KAAK,gBAAgB;AAAA,MACvD;AAAA,MACA,CAAC;AAAA,IACL;AAEA,4BAAwB;AAAA,MACpB,CAAC;AAAA,QACG;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACJ,MAAM;AACF,eAAO,KAAK,wCAAwC,MAAM;AAC1D,cAAM,SAAS,QAAQ,KAAK,CAAAA,YAAUA,QAAO,aAAa,QAAQ;AAClE,YAAI,CAAC,QAAQ;AACT,iBAAO,MAAM,0CAA0C,QAAQ;AAC/D;AAAA,QACJ;AACA,aAAK,mBAAmB,IAAI,QAAQ;AAAA,UAChC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACJ,CAAC;AAAA,MACL;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,8BAA8B;AAC1B,WAAO,CAAC,GAAG,KAAK,SAAS,EACpB,OAAO,aAAW,QAAQ,YAAY,CAAC,QAAQ,MAAM,EACrD,IAAI,cAAY;AAAA,MACb,MAAM,QAAQ;AAAA,MACd,QAAQ,QAAQ;AAAA,MAChB,YAAY,QAAQ;AAAA,MACpB,QAAQ,mBAAmB,qCAAgB,QAAQ,QAAQ,sBAAsB;AAAA,MACjF,cAAc,QAAQ,aAAa;AAAA,MACnC,QAAQ,QAAQ;AAAA,MAChB,0BAA0B,mBAAmB,qCAAgB,QAAQ,YAAY;AAAA,MACjF,qBAAqB,mBAAmB,qCAAgB,QAAQ,kBAAkB;AAAA,MAClF,6BAA6B,mBAAmB,qCAAgB,QAAQ,8BAA8B;AAAA,IAC1G,EAAE;AAAA,EACV;AAAA,EAEA,MAAM,QAAQ;AACV,UAAM,KAAK,uBAAuB;AAClC,eAAW,WAAW,KAAK,WAAW;AAClC,YAAM,SAAS,IAAI,KAAK;AACxB,WAAK,UAAU,OAAO,OAAO;AAAA,IACjC;AACA,eAAW,WAAW,KAAK,kBAAkB,OAAO,GAAG;AACnD,YAAM,SAAS,IAAI;AACnB,WAAK,kBAAkB,OAAO,QAAQ,MAAM;AAAA,IAChD;AAAA,EACJ;AACJ;",
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MatterFlowError } from \"../common/MatterError.js\";\nimport { Crypto } from \"../crypto/Crypto.js\";\nimport { CaseAuthenticatedTag } from \"../datatype/CaseAuthenticatedTag.js\";\nimport { FabricId } from \"../datatype/FabricId.js\";\nimport { NodeId } from \"../datatype/NodeId.js\";\nimport { Fabric } from \"../fabric/Fabric.js\";\nimport { Logger } from \"../log/Logger.js\";\nimport { MessageCounter } from \"../protocol/MessageCounter.js\";\nimport { StorageContext } from \"../storage/StorageContext.js\";\nimport { ByteArray } from \"../util/ByteArray.js\";\nimport { AsyncObservable, Observable } from \"../util/Observable.js\";\nimport { BasicSet } from \"../util/Set.js\";\nimport { InsecureSession } from \"./InsecureSession.js\";\nimport { SecureSession } from \"./SecureSession.js\";\nimport { SessionParameterOptions, SessionParameters } from \"./Session.js\";\n\nconst logger = Logger.get(\"SessionManager\");\n\nexport const UNICAST_UNSECURE_SESSION_ID = 0x0000;\n\nexport interface ResumptionRecord {\n sharedSecret: ByteArray;\n resumptionId: ByteArray;\n fabric: Fabric;\n peerNodeId: NodeId;\n sessionParameters: SessionParameters;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n}\n\ntype ResumptionStorageRecord = {\n nodeId: NodeId;\n sharedSecret: Uint8Array;\n resumptionId: Uint8Array;\n fabricId: FabricId;\n peerNodeId: NodeId;\n sessionParameters: {\n idleIntervalMs: number;\n activeIntervalMs: number;\n activeThresholdMs: number;\n };\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n};\n\nexport class SessionManager<ContextT> {\n readonly #insecureSessions = new Map<NodeId, InsecureSession<ContextT>>();\n readonly #sessions = new BasicSet<SecureSession<ContextT>>();\n #nextSessionId = Crypto.getRandomUInt16();\n #resumptionRecords = new Map<NodeId, ResumptionRecord>();\n readonly #sessionStorage: StorageContext;\n readonly #globalUnencryptedMessageCounter = new MessageCounter();\n readonly #subscriptionsChanged = new Observable<[session: SecureSession<ContextT>]>();\n readonly #sessionOpened = new Observable<[session: SecureSession<ContextT>]>();\n readonly #sessionClosed = new AsyncObservable<[session: SecureSession<ContextT>], void>();\n\n constructor(\n private readonly context: ContextT,\n sessionStorage: StorageContext,\n ) {\n this.#sessionStorage = sessionStorage;\n }\n\n get subscriptionsChanged() {\n return this.#subscriptionsChanged;\n }\n\n get sessionOpened() {\n return this.#sessionOpened;\n }\n\n get sessionClosed() {\n return this.#sessionClosed;\n }\n\n createUnsecureSession(options: {\n initiatorNodeId?: NodeId;\n sessionParameters?: SessionParameterOptions;\n isInitiator?: boolean;\n }) {\n const { initiatorNodeId, sessionParameters, isInitiator } = options;\n if (initiatorNodeId !== undefined) {\n if (this.#insecureSessions.has(initiatorNodeId)) {\n throw new MatterFlowError(`UnsecureSession with NodeId ${initiatorNodeId} already exists.`);\n }\n }\n while (true) {\n const session = new InsecureSession({\n context: this.context,\n messageCounter: this.#globalUnencryptedMessageCounter,\n closeCallback: async () => {\n logger.info(`End insecure session ${session.name}`);\n this.#insecureSessions.delete(session.nodeId);\n },\n initiatorNodeId,\n sessionParameters,\n isInitiator: isInitiator ?? false,\n });\n\n const ephermalNodeId = session.nodeId;\n if (this.#insecureSessions.has(ephermalNodeId)) continue;\n\n this.#insecureSessions.set(ephermalNodeId, session);\n return session;\n }\n }\n\n async createSecureSession(args: {\n sessionId: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n sharedSecret: ByteArray;\n salt: ByteArray;\n isInitiator: boolean;\n isResumption: boolean;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n }) {\n const {\n sessionId,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n sessionParameters,\n caseAuthenticatedTags,\n } = args;\n const session = await SecureSession.create({\n context: this.context,\n id: sessionId,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n closeCallback: async () => {\n logger.info(`End ${session.isPase ? \"PASE\" : \"CASE\"} session ${session.name}`);\n this.#sessions.delete(session);\n await this.#sessionClosed.emit(session);\n },\n sessionParameters,\n caseAuthenticatedTags,\n subscriptionChangedCallback: () => {\n this.#subscriptionsChanged.emit(session);\n },\n });\n\n this.#sessions.add(session);\n this.#sessionOpened.emit(session);\n\n // TODO: Add a maximum of sessions and respect/close the \"least recently used\" session. See Core Specs 4.10.1.1\n return session;\n }\n\n removeSession(sessionId: number) {\n const session = this.getSession(sessionId);\n if (session !== undefined) {\n this.#sessions.delete(session);\n }\n }\n\n async removeResumptionRecord(peerNodeId: NodeId) {\n this.#resumptionRecords.delete(peerNodeId);\n await this.storeResumptionRecords();\n }\n\n findOldestInactiveSession() {\n let oldestSession: SecureSession<ContextT> | undefined = undefined;\n for (const session of this.#sessions) {\n if (!oldestSession || session.activeTimestamp < oldestSession.activeTimestamp) {\n oldestSession = session;\n }\n }\n if (oldestSession === undefined) {\n throw new MatterFlowError(\"No session found to close and all session ids are taken.\");\n }\n return oldestSession;\n }\n\n async getNextAvailableSessionId() {\n for (let i = 0; i < 0xffff; i++) {\n const id = this.#nextSessionId;\n this.#nextSessionId = (this.#nextSessionId + 1) & 0xffff;\n if (this.#nextSessionId === 0) this.#nextSessionId++;\n\n if (this.getSession(id) === undefined) {\n return id;\n }\n }\n\n // All session ids are taken, search for the oldest unused session, and close it and re-use its ID\n const oldestSession = this.findOldestInactiveSession();\n await oldestSession.end(true, false);\n this.#nextSessionId = oldestSession.id;\n return this.#nextSessionId++;\n }\n\n getSession(sessionId: number) {\n return this.#sessions.get(\"id\", sessionId);\n }\n\n getPaseSession() {\n return [...this.#sessions].find(\n session => session.isSecure && session.isPase && !session.closingAfterExchangeFinished,\n ) as SecureSession<ContextT>;\n }\n\n getSessionForNode(fabric: Fabric, nodeId: NodeId) {\n //TODO: It can have multiple sessions for one node ...\n return [...this.#sessions].find(session => {\n if (!session.isSecure) return false;\n const secureSession = session as SecureSession<any>;\n return secureSession.fabric?.fabricId === fabric.fabricId && secureSession.peerNodeId === nodeId;\n });\n }\n\n async removeAllSessionsForNode(nodeId: NodeId, sendClose = false) {\n for (const session of this.#sessions) {\n if (!session.isSecure) continue;\n const secureSession = session as SecureSession<any>;\n if (secureSession.peerNodeId === nodeId) {\n await secureSession.destroy(sendClose, false);\n }\n }\n }\n\n getUnsecureSession(sourceNodeId?: NodeId) {\n if (sourceNodeId === undefined) {\n return this.#insecureSessions.get(NodeId.UNSPECIFIED_NODE_ID);\n }\n return this.#insecureSessions.get(sourceNodeId);\n }\n\n findGroupSession(groupId: number, groupSessionId: number) {\n // Use groupsession id to find the key ??!!\n // The Group Session ID MAY help receiving nodes efficiently locate the Operational Group Key used to encrypt an incoming groupcast message. It SHALL NOT be used as the sole means to locate the asso\u00AD ciated Operational Group Key, since it MAY collide within the fabric. Instead, the Group Session ID provides receiving nodes a means to identify Operational Group Key candidates without the need to first attempt to decrypt groupcast messages using all available keys.\n // On receipt of a message of Group Session Type, all valid, installed, operational group key candidates referenced by the given Group Session ID SHALL be attempted until authentication is passed or there are no more operational group keys to try. This is done because the same Group Session ID might arise from different keys. The chance of a Group Session ID collision is 2-16 but the chance of both a Group Session ID collision and the message MIC matching two different operational group keys is 2-80.\n\n // TODO\n throw new Error(`Not implemented ${groupId} ${groupSessionId}`);\n }\n\n findResumptionRecordById(resumptionId: ByteArray) {\n return [...this.#resumptionRecords.values()].find(record => record.resumptionId.equals(resumptionId));\n }\n\n findResumptionRecordByNodeId(nodeId: NodeId) {\n return this.#resumptionRecords.get(nodeId);\n }\n\n async saveResumptionRecord(resumptionRecord: ResumptionRecord) {\n this.#resumptionRecords.set(resumptionRecord.peerNodeId, resumptionRecord);\n await this.storeResumptionRecords();\n }\n\n async updateFabricForResumptionRecords(fabric: Fabric) {\n const record = this.#resumptionRecords.get(fabric.rootNodeId);\n if (record === undefined) {\n throw new MatterFlowError(\"Resumption record not found. Should never happen.\");\n }\n this.#resumptionRecords.set(fabric.rootNodeId, { ...record, fabric });\n await this.storeResumptionRecords();\n }\n\n async storeResumptionRecords() {\n await this.#sessionStorage.set(\n \"resumptionRecords\",\n [...this.#resumptionRecords].map(\n ([\n nodeId,\n { sharedSecret, resumptionId, peerNodeId, fabric, sessionParameters, caseAuthenticatedTags },\n ]) =>\n ({\n nodeId,\n sharedSecret,\n resumptionId,\n fabricId: fabric.fabricId,\n peerNodeId: peerNodeId,\n sessionParameters,\n caseAuthenticatedTags,\n }) as ResumptionStorageRecord,\n ),\n );\n }\n\n async initFromStorage(fabrics: Fabric[]) {\n const storedResumptionRecords = await this.#sessionStorage.get<ResumptionStorageRecord[]>(\n \"resumptionRecords\",\n [],\n );\n\n storedResumptionRecords.forEach(\n ({\n nodeId,\n sharedSecret,\n resumptionId,\n fabricId,\n peerNodeId,\n sessionParameters,\n caseAuthenticatedTags,\n }) => {\n logger.info(\"restoring resumption record for node\", nodeId);\n const fabric = fabrics.find(fabric => fabric.fabricId === fabricId);\n if (!fabric) {\n logger.error(\"fabric not found for resumption record\", fabricId);\n return;\n }\n this.#resumptionRecords.set(nodeId, {\n sharedSecret,\n resumptionId,\n fabric,\n peerNodeId,\n sessionParameters,\n caseAuthenticatedTags,\n });\n },\n );\n }\n\n getActiveSessionInformation() {\n return [...this.#sessions]\n .filter(session => session.isSecure && !session.isPase)\n .map(session => ({\n name: session.name,\n nodeId: session.nodeId,\n peerNodeId: session.peerNodeId,\n fabric: session instanceof SecureSession ? session.fabric?.externalInformation : undefined,\n isPeerActive: session.isPeerActive(),\n secure: session.isSecure,\n lastInteractionTimestamp: session instanceof SecureSession ? session.timestamp : undefined,\n lastActiveTimestamp: session instanceof SecureSession ? session.activeTimestamp : undefined,\n numberOfActiveSubscriptions: session instanceof SecureSession ? session.numberOfActiveSubscriptions : 0,\n }));\n }\n\n async clearSubscriptionsForNode(nodeId: NodeId, flushSubscriptions?: boolean) {\n for (const session of this.#sessions) {\n if (session.peerNodeId === nodeId) {\n await session.clearSubscriptions(flushSubscriptions);\n }\n }\n }\n\n async close() {\n await this.storeResumptionRecords();\n for (const session of this.#sessions) {\n await session?.end(false);\n this.#sessions.delete(session);\n }\n for (const session of this.#insecureSessions.values()) {\n await session?.end();\n this.#insecureSessions.delete(session.nodeId);\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["fabric"]
|
|
7
7
|
}
|
|
@@ -80,6 +80,7 @@ export declare class MatterDevice {
|
|
|
80
80
|
session: Session<MatterDevice>;
|
|
81
81
|
channel: Channel<ByteArray>;
|
|
82
82
|
}>;
|
|
83
|
+
clearSubscriptionsForNode(peerNodeId: NodeId, flushSubscriptions?: boolean): Promise<void>;
|
|
83
84
|
close(): Promise<void>;
|
|
84
85
|
getActiveSessionInformation(): {
|
|
85
86
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MatterDevice.d.ts","sourceRoot":"","sources":["../../src/MatterDevice.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MatterDevice.d.ts","sourceRoot":"","sources":["../../src/MatterDevice.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/MatterDevice.js
CHANGED
|
@@ -378,6 +378,9 @@ class MatterDevice {
|
|
|
378
378
|
}
|
|
379
379
|
return { session, channel: await networkInterface.openChannel(device.addresses[0]) };
|
|
380
380
|
}
|
|
381
|
+
async clearSubscriptionsForNode(peerNodeId, flushSubscriptions) {
|
|
382
|
+
await this.#sessionManager.clearSubscriptionsForNode(peerNodeId, flushSubscriptions);
|
|
383
|
+
}
|
|
381
384
|
async close() {
|
|
382
385
|
this.#isClosing = true;
|
|
383
386
|
await this.endCommissioning();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/MatterDevice.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Important note: This file is part of the legacy matter-node (internal) API and should not be used anymore directly!\n * Please use the new API classes!\n * @deprecated\n */\n\nimport {\n DEVICE_ANNOUNCEMENT_DURATION_MS,\n DEVICE_ANNOUNCEMENT_INTERVAL_MS,\n} from \"./behavior/definitions/administrator-commissioning/AdministratorCommissioningConstants.js\";\nimport { CommissioningOptions } from \"./behavior/system/commissioning/CommissioningOptions.js\";\nimport { AdministratorCommissioning } from \"./cluster/definitions/AdministratorCommissioningCluster.js\";\n\nimport { Channel } from \"./common/Channel.js\";\nimport { FailsafeContext } from \"./common/FailsafeContext.js\";\nimport { InstanceBroadcaster } from \"./common/InstanceBroadcaster.js\";\nimport { Lifecycle } from \"./common/Lifecycle.js\";\nimport { InternalError, MatterFlowError } from \"./common/MatterError.js\";\nimport { Scanner } from \"./common/Scanner.js\";\nimport { TransportInterface } from \"./common/TransportInterface.js\";\nimport { Crypto } from \"./crypto/Crypto.js\";\nimport { FabricIndex } from \"./datatype/FabricIndex.js\";\nimport { NodeId } from \"./datatype/NodeId.js\";\nimport { Fabric } from \"./fabric/Fabric.js\";\nimport { FabricAction, FabricManager } from \"./fabric/FabricManager.js\";\nimport { Diagnostic } from \"./log/Diagnostic.js\";\nimport { Logger } from \"./log/Logger.js\";\nimport { NetInterface, isNetworkInterface } from \"./net/NetInterface.js\";\nimport { NetworkError } from \"./net/Network.js\";\nimport { ChannelManager } from \"./protocol/ChannelManager.js\";\nimport { ExchangeManager } from \"./protocol/ExchangeManager.js\";\nimport { ProtocolHandler } from \"./protocol/ProtocolHandler.js\";\nimport { StatusCode, StatusResponseError } from \"./protocol/interaction/StatusCode.js\";\nimport { SecureChannelProtocol } from \"./protocol/securechannel/SecureChannelProtocol.js\";\nimport { Session } from \"./session/Session.js\";\nimport { ResumptionRecord, SessionManager } from \"./session/SessionManager.js\";\nimport { PaseServer } from \"./session/pase/PaseServer.js\";\nimport { StorageContext } from \"./storage/StorageContext.js\";\nimport { Time, Timer } from \"./time/Time.js\";\nimport { AsyncConstruction, asyncNew } from \"./util/AsyncConstruction.js\";\nimport { ByteArray } from \"./util/ByteArray.js\";\nimport { Mutex } from \"./util/Mutex.js\";\n\nconst logger = Logger.get(\"MatterDevice\");\n\nexport class MatterDevice {\n private readonly scanners = new Array<Scanner>();\n private readonly broadcasters = new Array<InstanceBroadcaster>();\n private readonly transportInterfaces = new Array<TransportInterface | NetInterface>();\n private readonly channelManager: ChannelManager;\n private readonly secureChannelProtocol = new SecureChannelProtocol(() => this.endCommissioning());\n private activeCommissioningMode = AdministratorCommissioning.CommissioningWindowStatus.WindowNotOpen;\n private activeCommissioningEndCallback?: () => void;\n private announceInterval: Timer;\n private announcementStartedTime: number | null = null;\n #isClosing = false;\n readonly #exchangeManager;\n readonly #fabricManager: FabricManager;\n readonly #sessionManager: SessionManager<MatterDevice>;\n #failsafeContext?: FailsafeContext;\n\n // Currently we do not put much effort into synchronizing announcements as it probably isn't really necessary. But\n // this mutex prevents automated announcements from piling up and allows us to ensure announcements are complete\n // on close\n #announcementMutex = new Mutex(this);\n #construction: AsyncConstruction<MatterDevice>;\n\n get construction() {\n return this.#construction;\n }\n\n static async create(\n sessionStorage: StorageContext,\n fabricStorage: StorageContext,\n getCommissioningConfig: () => CommissioningOptions.Configuration,\n minimumCaseSessionsPerFabricAndNode = 3,\n commissioningChangedCallback: (fabricIndex: FabricIndex, fabricAction: FabricAction) => void,\n sessionChangedCallback: (fabricIndex: FabricIndex) => void,\n ) {\n return asyncNew(\n MatterDevice,\n sessionStorage,\n fabricStorage,\n getCommissioningConfig,\n minimumCaseSessionsPerFabricAndNode,\n commissioningChangedCallback,\n sessionChangedCallback,\n );\n }\n\n constructor(\n readonly sessionStorage: StorageContext,\n readonly fabricStorage: StorageContext,\n private readonly getCommissioningConfig: () => CommissioningOptions.Configuration,\n minimumCaseSessionsPerFabricAndNode: number,\n private readonly commissioningChangedCallback: (fabricIndex: FabricIndex, fabricAction: FabricAction) => void,\n private readonly sessionChangedCallback: (fabricIndex: FabricIndex) => void,\n ) {\n this.channelManager = new ChannelManager(minimumCaseSessionsPerFabricAndNode);\n\n this.#fabricManager = new FabricManager(fabricStorage);\n\n this.#fabricManager.events.deleted.on(async fabric => {\n const { fabricIndex, rootNodeId } = fabric;\n // When fabric is removed, also remove the resumption record\n await this.#sessionManager.removeResumptionRecord(rootNodeId);\n this.commissioningChangedCallback(fabricIndex, FabricAction.Removed);\n if (this.#fabricManager.getFabrics().length === 0) {\n // Last fabric got removed, so expire all announcements\n await this.expireAllFabricAnnouncements();\n }\n });\n this.#fabricManager.events.updated.on(({ fabricIndex }) =>\n this.commissioningChangedCallback(fabricIndex, FabricAction.Updated),\n );\n\n this.#sessionManager = new SessionManager(this, sessionStorage);\n\n this.#exchangeManager = new ExchangeManager<MatterDevice>(this.#sessionManager, this.channelManager);\n\n this.addProtocolHandler(this.secureChannelProtocol);\n\n this.announceInterval = Time.getPeriodicTimer(\"Server node announcement\", DEVICE_ANNOUNCEMENT_INTERVAL_MS, () =>\n // Announcement needs to await a previous announcement because otherwise in testing at least announcement\n // may crash if started simultaneously\n this.#announcementMutex.run(() => this.announce()),\n );\n\n this.#sessionManager.sessionOpened.on(session => {\n if (session.fabric) {\n this.sessionChangedCallback(session.fabric.fabricIndex);\n }\n });\n\n this.#sessionManager.sessionClosed.on(async session => {\n if (!session.closingAfterExchangeFinished) {\n // Delayed closing is executed when exchange is closed\n await this.exchangeManager.closeSession(session);\n }\n const currentFabric = session.fabric;\n if (currentFabric !== undefined) {\n this.sessionChangedCallback(currentFabric.fabricIndex);\n }\n if (this.isClosing) {\n return;\n }\n // When a session closes, announce existing fabrics again so that controller can detect the device again.\n // When session was closed and no fabric exist anymore then this is triggering a factory reset in upper layer\n // and it would be not good to announce a commissionable device and then reset that again with the factory reset\n if (this.#fabricManager.getFabrics().length > 0 || !currentFabric) {\n await this.startAnnouncement();\n }\n });\n\n this.#sessionManager.subscriptionsChanged.on(session => {\n const currentFabric = session.fabric;\n if (currentFabric !== undefined) {\n this.sessionChangedCallback(currentFabric.fabricIndex);\n }\n });\n\n this.#construction = AsyncConstruction(this, async () => {\n await this.#fabricManager.initFromStorage();\n\n // Attach added events delayed because initialization from storage would else trigger it\n this.#fabricManager.events.added.on(({ fabricIndex }) =>\n this.commissioningChangedCallback(fabricIndex, FabricAction.Added),\n );\n\n await this.#sessionManager.initFromStorage(this.#fabricManager.getFabrics());\n });\n }\n\n get fabricManager() {\n return this.#fabricManager;\n }\n\n get sessionManager() {\n return this.#sessionManager;\n }\n\n get exchangeManager() {\n return this.#exchangeManager;\n }\n\n get failsafeContext() {\n this.assertFailSafeArmed();\n return this.#failsafeContext as FailsafeContext;\n }\n\n get isClosing() {\n return this.#isClosing;\n }\n\n async beginTimed(failsafeContext: FailsafeContext) {\n await failsafeContext.construction;\n\n this.#failsafeContext = failsafeContext;\n\n this.#fabricManager.events.added.on(fabric => {\n const fabrics = this.#fabricManager.getFabrics();\n this.sendFabricAnnouncements(fabrics, true).catch(error =>\n logger.warn(`Error sending Fabric announcement for Index ${fabric.fabricIndex}`, error),\n );\n logger.info(\"Announce done\", Diagnostic.dict({ fabric: fabric.fabricId, fabricIndex: fabric.fabricIndex }));\n });\n\n failsafeContext.commissioned.on(async () => await this.endCommissioning());\n\n failsafeContext.construction.change.on(status => {\n if (status === Lifecycle.Status.Destroyed) {\n this.#failsafeContext = undefined;\n }\n });\n }\n\n assertFailSafeArmed(message?: string) {\n if (this.isFailsafeArmed()) return;\n throw new StatusResponseError(\n message ?? \"Failsafe timer needs to be armed to execute this action.\",\n StatusCode.FailsafeRequired,\n );\n }\n\n isFailsafeArmed() {\n return this.#failsafeContext !== undefined;\n }\n\n addScanner(scanner: Scanner) {\n this.scanners.push(scanner);\n return this;\n }\n\n hasBroadcaster(broadcaster: InstanceBroadcaster) {\n return this.broadcasters.includes(broadcaster);\n }\n\n addBroadcaster(broadcaster: InstanceBroadcaster) {\n this.broadcasters.push(broadcaster);\n return this;\n }\n\n async deleteBroadcaster(broadcaster: InstanceBroadcaster) {\n const pos = this.broadcasters.findIndex(b => b === broadcaster);\n if (pos !== -1) {\n this.broadcasters.splice(pos, 1);\n await broadcaster.expireAllAnnouncements();\n }\n }\n\n addTransportInterface(transport: TransportInterface) {\n this.exchangeManager.addTransportInterface(transport);\n this.transportInterfaces.push(transport);\n return this;\n }\n\n async deleteTransportInterface(transport: TransportInterface) {\n const pos = this.transportInterfaces.findIndex(t => t === transport);\n if (pos !== -1) {\n this.transportInterfaces.splice(pos, 1);\n await transport.close();\n }\n }\n\n hasProtocolHandler(protocolId: number) {\n return this.exchangeManager.hasProtocolHandler(protocolId);\n }\n\n addProtocolHandler(protocol: ProtocolHandler<MatterDevice>) {\n this.exchangeManager.addProtocolHandler(protocol);\n return this;\n }\n\n async start() {\n await this.startAnnouncement();\n }\n\n async startAnnouncement() {\n if (this.isClosing) return;\n if (this.announceInterval.isRunning) {\n this.announceInterval.stop();\n }\n this.announcementStartedTime = Time.nowMs();\n this.announceInterval.start();\n await this.announce();\n }\n\n async expireAllFabricAnnouncements() {\n for (const broadcaster of this.broadcasters) {\n await broadcaster.expireAllAnnouncements();\n }\n }\n\n async announce(announceOnce = false) {\n if (!announceOnce) {\n // Stop announcement if duration is reached\n if (\n this.announcementStartedTime !== null &&\n Time.nowMs() - this.announcementStartedTime > DEVICE_ANNOUNCEMENT_DURATION_MS\n ) {\n await this.endCommissioning();\n logger.debug(\"Announcement duration reached, stop announcing\");\n return;\n }\n if (this.activeCommissioningMode !== AdministratorCommissioning.CommissioningWindowStatus.WindowNotOpen) {\n // Re-Announce but do not re-set Fabrics\n for (const broadcaster of this.broadcasters) {\n await broadcaster.announce();\n }\n return;\n }\n }\n const fabrics = this.#fabricManager.getFabrics();\n if (fabrics.length) {\n let fabricsWithoutSessions = 0;\n for (const fabric of fabrics) {\n const session = this.#sessionManager.getSessionForNode(fabric, fabric.rootNodeId);\n if (session === undefined || !session.isSecure || session.numberOfActiveSubscriptions === 0) {\n fabricsWithoutSessions++;\n logger.debug(\"Announcing\", Diagnostic.dict({ fabric: fabric.fabricId }));\n }\n }\n for (const broadcaster of this.broadcasters) {\n await broadcaster.setFabrics(fabrics);\n if (fabricsWithoutSessions > 0) {\n await broadcaster.announce();\n }\n }\n } else {\n // No fabric paired yet, so announce as \"ready for commissioning\"\n // And expire operational Fabric announcements (if fabric got just deleted)\n await this.expireAllFabricAnnouncements();\n await this.allowBasicCommissioning();\n }\n }\n\n private async announceAsCommissionable(\n mode: AdministratorCommissioning.CommissioningWindowStatus,\n activeCommissioningEndCallback?: () => void,\n discriminator?: number,\n ) {\n if (this.activeCommissioningMode !== AdministratorCommissioning.CommissioningWindowStatus.WindowNotOpen) {\n throw new InternalError(\n `Commissioning window already open with different mode (${this.activeCommissioningMode})!`,\n );\n }\n if (this.activeCommissioningEndCallback !== undefined) {\n throw new InternalError(\"Commissioning window already open with different callback!\");\n }\n this.activeCommissioningMode = mode;\n if (activeCommissioningEndCallback !== undefined) {\n this.activeCommissioningEndCallback = activeCommissioningEndCallback;\n }\n // MDNS is sent in parallel\n // TODO - untracked promise\n this.sendCommissionableAnnouncement(mode, discriminator).catch(error =>\n logger.warn(\"Error sending announcement\", error),\n );\n }\n\n async sendCommissionableAnnouncement(\n mode: AdministratorCommissioning.CommissioningWindowStatus,\n discriminator?: number,\n ) {\n const commissioningConfig = this.getCommissioningConfig();\n for (const broadcaster of this.broadcasters) {\n await broadcaster.setCommissionMode(\n mode === AdministratorCommissioning.CommissioningWindowStatus.EnhancedWindowOpen ? 2 : 1,\n {\n ...commissioningConfig.productDescription,\n discriminator: discriminator ?? commissioningConfig.discriminator,\n },\n );\n }\n await this.startAnnouncement();\n }\n\n async getNextAvailableSessionId() {\n return this.#sessionManager.getNextAvailableSessionId();\n }\n\n findFabricFromDestinationId(destinationId: ByteArray, peerRandom: ByteArray) {\n return this.#fabricManager.findFabricFromDestinationId(destinationId, peerRandom);\n }\n\n async sendFabricAnnouncements(fabrics: Fabric[], expireCommissioningAnnouncement = false) {\n for (const broadcaster of this.broadcasters) {\n await broadcaster.setFabrics(fabrics, expireCommissioningAnnouncement);\n await broadcaster.announce();\n }\n }\n\n getFabricByIndex(fabricIndex: FabricIndex) {\n return this.#fabricManager.getFabrics().find(fabric => fabric.fabricIndex === fabricIndex);\n }\n\n initiateExchange(fabric: Fabric, nodeId: NodeId, protocolId: number) {\n return this.exchangeManager.initiateExchange(fabric, nodeId, protocolId);\n }\n\n findResumptionRecordById(resumptionId: ByteArray) {\n return this.#sessionManager.findResumptionRecordById(resumptionId);\n }\n\n async saveResumptionRecord(resumptionRecord: ResumptionRecord) {\n return this.#sessionManager.saveResumptionRecord(resumptionRecord);\n }\n\n getFabrics() {\n return this.#fabricManager.getFabrics();\n }\n\n isCommissioned() {\n return !!this.#fabricManager.getFabrics().length;\n }\n\n async allowEnhancedCommissioning(\n discriminator: number,\n paseServer: PaseServer,\n commissioningEndCallback: () => void,\n ) {\n if (this.activeCommissioningMode === AdministratorCommissioning.CommissioningWindowStatus.BasicWindowOpen) {\n throw new MatterFlowError(\n \"Basic commissioning window is already open! Can not set Enhanced commissioning mode.\",\n );\n }\n\n this.secureChannelProtocol.setPaseCommissioner(paseServer);\n await this.announceAsCommissionable(\n AdministratorCommissioning.CommissioningWindowStatus.EnhancedWindowOpen,\n commissioningEndCallback,\n discriminator,\n );\n }\n\n async allowBasicCommissioning(commissioningEndCallback?: () => void) {\n if (this.activeCommissioningMode === AdministratorCommissioning.CommissioningWindowStatus.EnhancedWindowOpen) {\n throw new MatterFlowError(\n \"Enhanced commissioning window is already open! Can not set Basic commissioning mode.\",\n );\n }\n\n this.secureChannelProtocol.setPaseCommissioner(\n await PaseServer.fromPin(this.getCommissioningConfig().passcode, {\n iterations: 1000,\n salt: Crypto.get().getRandomData(32),\n }),\n );\n\n await this.announceAsCommissionable(\n AdministratorCommissioning.CommissioningWindowStatus.BasicWindowOpen,\n commissioningEndCallback,\n );\n }\n\n async endCommissioning() {\n logger.debug(\"Commissioning mode ended, stop announcements.\");\n // Remove PASE responder when we close enhanced commissioning window or node is commissioned\n if (\n this.activeCommissioningMode === AdministratorCommissioning.CommissioningWindowStatus.EnhancedWindowOpen ||\n this.isCommissioned()\n ) {\n this.secureChannelProtocol.removePaseCommissioner();\n }\n this.activeCommissioningMode = AdministratorCommissioning.CommissioningWindowStatus.WindowNotOpen;\n this.announceInterval.stop();\n this.announcementStartedTime = null;\n if (this.activeCommissioningEndCallback !== undefined) {\n const activeCommissioningEndCallback = this.activeCommissioningEndCallback;\n this.activeCommissioningEndCallback = undefined;\n activeCommissioningEndCallback();\n }\n for (const broadcaster of this.broadcasters) {\n await broadcaster.expireCommissioningAnnouncement();\n }\n logger.info(\"All announcements expired\");\n }\n\n existsOpenPaseSession() {\n return !!this.#sessionManager.getPaseSession();\n }\n\n async findDevice(\n fabric: Fabric,\n nodeId: NodeId,\n timeOutSeconds = 5,\n ): Promise<undefined | { session: Session<MatterDevice>; channel: Channel<ByteArray> }> {\n // TODO: return the first not undefined answer or undefined\n const device = await this.scanners[0].findOperationalDevice(fabric, nodeId, timeOutSeconds);\n if (device === undefined) return undefined;\n const session = this.#sessionManager.getSessionForNode(fabric, nodeId);\n if (session === undefined) return undefined;\n // TODO: have the interface and scanner linked\n const networkInterface = this.transportInterfaces.find(netInterface => isNetworkInterface(netInterface));\n if (networkInterface === undefined || !isNetworkInterface(networkInterface)) {\n throw new NetworkError(\"No network interface found\");\n } // TODO meeehhh\n return { session, channel: await networkInterface.openChannel(device.addresses[0]) };\n }\n\n async close() {\n this.#isClosing = true;\n await this.endCommissioning();\n await this.#announcementMutex;\n for (const broadcaster of this.broadcasters) {\n await broadcaster.close();\n }\n if (this.#failsafeContext) {\n await this.#failsafeContext.close();\n this.#failsafeContext = undefined;\n }\n await this.exchangeManager.close();\n await this.#sessionManager.close();\n await this.channelManager.close();\n for (const transportInterface of this.transportInterfaces) {\n await transportInterface.close();\n }\n }\n\n getActiveSessionInformation() {\n return this.#sessionManager.getActiveSessionInformation();\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Important note: This file is part of the legacy matter-node (internal) API and should not be used anymore directly!\n * Please use the new API classes!\n * @deprecated\n */\n\nimport {\n DEVICE_ANNOUNCEMENT_DURATION_MS,\n DEVICE_ANNOUNCEMENT_INTERVAL_MS,\n} from \"./behavior/definitions/administrator-commissioning/AdministratorCommissioningConstants.js\";\nimport { CommissioningOptions } from \"./behavior/system/commissioning/CommissioningOptions.js\";\nimport { AdministratorCommissioning } from \"./cluster/definitions/AdministratorCommissioningCluster.js\";\n\nimport { Channel } from \"./common/Channel.js\";\nimport { FailsafeContext } from \"./common/FailsafeContext.js\";\nimport { InstanceBroadcaster } from \"./common/InstanceBroadcaster.js\";\nimport { Lifecycle } from \"./common/Lifecycle.js\";\nimport { InternalError, MatterFlowError } from \"./common/MatterError.js\";\nimport { Scanner } from \"./common/Scanner.js\";\nimport { TransportInterface } from \"./common/TransportInterface.js\";\nimport { Crypto } from \"./crypto/Crypto.js\";\nimport { FabricIndex } from \"./datatype/FabricIndex.js\";\nimport { NodeId } from \"./datatype/NodeId.js\";\nimport { Fabric } from \"./fabric/Fabric.js\";\nimport { FabricAction, FabricManager } from \"./fabric/FabricManager.js\";\nimport { Diagnostic } from \"./log/Diagnostic.js\";\nimport { Logger } from \"./log/Logger.js\";\nimport { NetInterface, isNetworkInterface } from \"./net/NetInterface.js\";\nimport { NetworkError } from \"./net/Network.js\";\nimport { ChannelManager } from \"./protocol/ChannelManager.js\";\nimport { ExchangeManager } from \"./protocol/ExchangeManager.js\";\nimport { ProtocolHandler } from \"./protocol/ProtocolHandler.js\";\nimport { StatusCode, StatusResponseError } from \"./protocol/interaction/StatusCode.js\";\nimport { SecureChannelProtocol } from \"./protocol/securechannel/SecureChannelProtocol.js\";\nimport { Session } from \"./session/Session.js\";\nimport { ResumptionRecord, SessionManager } from \"./session/SessionManager.js\";\nimport { PaseServer } from \"./session/pase/PaseServer.js\";\nimport { StorageContext } from \"./storage/StorageContext.js\";\nimport { Time, Timer } from \"./time/Time.js\";\nimport { AsyncConstruction, asyncNew } from \"./util/AsyncConstruction.js\";\nimport { ByteArray } from \"./util/ByteArray.js\";\nimport { Mutex } from \"./util/Mutex.js\";\n\nconst logger = Logger.get(\"MatterDevice\");\n\nexport class MatterDevice {\n private readonly scanners = new Array<Scanner>();\n private readonly broadcasters = new Array<InstanceBroadcaster>();\n private readonly transportInterfaces = new Array<TransportInterface | NetInterface>();\n private readonly channelManager: ChannelManager;\n private readonly secureChannelProtocol = new SecureChannelProtocol(() => this.endCommissioning());\n private activeCommissioningMode = AdministratorCommissioning.CommissioningWindowStatus.WindowNotOpen;\n private activeCommissioningEndCallback?: () => void;\n private announceInterval: Timer;\n private announcementStartedTime: number | null = null;\n #isClosing = false;\n readonly #exchangeManager;\n readonly #fabricManager: FabricManager;\n readonly #sessionManager: SessionManager<MatterDevice>;\n #failsafeContext?: FailsafeContext;\n\n // Currently we do not put much effort into synchronizing announcements as it probably isn't really necessary. But\n // this mutex prevents automated announcements from piling up and allows us to ensure announcements are complete\n // on close\n #announcementMutex = new Mutex(this);\n #construction: AsyncConstruction<MatterDevice>;\n\n get construction() {\n return this.#construction;\n }\n\n static async create(\n sessionStorage: StorageContext,\n fabricStorage: StorageContext,\n getCommissioningConfig: () => CommissioningOptions.Configuration,\n minimumCaseSessionsPerFabricAndNode = 3,\n commissioningChangedCallback: (fabricIndex: FabricIndex, fabricAction: FabricAction) => void,\n sessionChangedCallback: (fabricIndex: FabricIndex) => void,\n ) {\n return asyncNew(\n MatterDevice,\n sessionStorage,\n fabricStorage,\n getCommissioningConfig,\n minimumCaseSessionsPerFabricAndNode,\n commissioningChangedCallback,\n sessionChangedCallback,\n );\n }\n\n constructor(\n readonly sessionStorage: StorageContext,\n readonly fabricStorage: StorageContext,\n private readonly getCommissioningConfig: () => CommissioningOptions.Configuration,\n minimumCaseSessionsPerFabricAndNode: number,\n private readonly commissioningChangedCallback: (fabricIndex: FabricIndex, fabricAction: FabricAction) => void,\n private readonly sessionChangedCallback: (fabricIndex: FabricIndex) => void,\n ) {\n this.channelManager = new ChannelManager(minimumCaseSessionsPerFabricAndNode);\n\n this.#fabricManager = new FabricManager(fabricStorage);\n\n this.#fabricManager.events.deleted.on(async fabric => {\n const { fabricIndex, rootNodeId } = fabric;\n // When fabric is removed, also remove the resumption record\n await this.#sessionManager.removeResumptionRecord(rootNodeId);\n this.commissioningChangedCallback(fabricIndex, FabricAction.Removed);\n if (this.#fabricManager.getFabrics().length === 0) {\n // Last fabric got removed, so expire all announcements\n await this.expireAllFabricAnnouncements();\n }\n });\n this.#fabricManager.events.updated.on(({ fabricIndex }) =>\n this.commissioningChangedCallback(fabricIndex, FabricAction.Updated),\n );\n\n this.#sessionManager = new SessionManager(this, sessionStorage);\n\n this.#exchangeManager = new ExchangeManager<MatterDevice>(this.#sessionManager, this.channelManager);\n\n this.addProtocolHandler(this.secureChannelProtocol);\n\n this.announceInterval = Time.getPeriodicTimer(\"Server node announcement\", DEVICE_ANNOUNCEMENT_INTERVAL_MS, () =>\n // Announcement needs to await a previous announcement because otherwise in testing at least announcement\n // may crash if started simultaneously\n this.#announcementMutex.run(() => this.announce()),\n );\n\n this.#sessionManager.sessionOpened.on(session => {\n if (session.fabric) {\n this.sessionChangedCallback(session.fabric.fabricIndex);\n }\n });\n\n this.#sessionManager.sessionClosed.on(async session => {\n if (!session.closingAfterExchangeFinished) {\n // Delayed closing is executed when exchange is closed\n await this.exchangeManager.closeSession(session);\n }\n const currentFabric = session.fabric;\n if (currentFabric !== undefined) {\n this.sessionChangedCallback(currentFabric.fabricIndex);\n }\n if (this.isClosing) {\n return;\n }\n // When a session closes, announce existing fabrics again so that controller can detect the device again.\n // When session was closed and no fabric exist anymore then this is triggering a factory reset in upper layer\n // and it would be not good to announce a commissionable device and then reset that again with the factory reset\n if (this.#fabricManager.getFabrics().length > 0 || !currentFabric) {\n await this.startAnnouncement();\n }\n });\n\n this.#sessionManager.subscriptionsChanged.on(session => {\n const currentFabric = session.fabric;\n if (currentFabric !== undefined) {\n this.sessionChangedCallback(currentFabric.fabricIndex);\n }\n });\n\n this.#construction = AsyncConstruction(this, async () => {\n await this.#fabricManager.initFromStorage();\n\n // Attach added events delayed because initialization from storage would else trigger it\n this.#fabricManager.events.added.on(({ fabricIndex }) =>\n this.commissioningChangedCallback(fabricIndex, FabricAction.Added),\n );\n\n await this.#sessionManager.initFromStorage(this.#fabricManager.getFabrics());\n });\n }\n\n get fabricManager() {\n return this.#fabricManager;\n }\n\n get sessionManager() {\n return this.#sessionManager;\n }\n\n get exchangeManager() {\n return this.#exchangeManager;\n }\n\n get failsafeContext() {\n this.assertFailSafeArmed();\n return this.#failsafeContext as FailsafeContext;\n }\n\n get isClosing() {\n return this.#isClosing;\n }\n\n async beginTimed(failsafeContext: FailsafeContext) {\n await failsafeContext.construction;\n\n this.#failsafeContext = failsafeContext;\n\n this.#fabricManager.events.added.on(fabric => {\n const fabrics = this.#fabricManager.getFabrics();\n this.sendFabricAnnouncements(fabrics, true).catch(error =>\n logger.warn(`Error sending Fabric announcement for Index ${fabric.fabricIndex}`, error),\n );\n logger.info(\"Announce done\", Diagnostic.dict({ fabric: fabric.fabricId, fabricIndex: fabric.fabricIndex }));\n });\n\n failsafeContext.commissioned.on(async () => await this.endCommissioning());\n\n failsafeContext.construction.change.on(status => {\n if (status === Lifecycle.Status.Destroyed) {\n this.#failsafeContext = undefined;\n }\n });\n }\n\n assertFailSafeArmed(message?: string) {\n if (this.isFailsafeArmed()) return;\n throw new StatusResponseError(\n message ?? \"Failsafe timer needs to be armed to execute this action.\",\n StatusCode.FailsafeRequired,\n );\n }\n\n isFailsafeArmed() {\n return this.#failsafeContext !== undefined;\n }\n\n addScanner(scanner: Scanner) {\n this.scanners.push(scanner);\n return this;\n }\n\n hasBroadcaster(broadcaster: InstanceBroadcaster) {\n return this.broadcasters.includes(broadcaster);\n }\n\n addBroadcaster(broadcaster: InstanceBroadcaster) {\n this.broadcasters.push(broadcaster);\n return this;\n }\n\n async deleteBroadcaster(broadcaster: InstanceBroadcaster) {\n const pos = this.broadcasters.findIndex(b => b === broadcaster);\n if (pos !== -1) {\n this.broadcasters.splice(pos, 1);\n await broadcaster.expireAllAnnouncements();\n }\n }\n\n addTransportInterface(transport: TransportInterface) {\n this.exchangeManager.addTransportInterface(transport);\n this.transportInterfaces.push(transport);\n return this;\n }\n\n async deleteTransportInterface(transport: TransportInterface) {\n const pos = this.transportInterfaces.findIndex(t => t === transport);\n if (pos !== -1) {\n this.transportInterfaces.splice(pos, 1);\n await transport.close();\n }\n }\n\n hasProtocolHandler(protocolId: number) {\n return this.exchangeManager.hasProtocolHandler(protocolId);\n }\n\n addProtocolHandler(protocol: ProtocolHandler<MatterDevice>) {\n this.exchangeManager.addProtocolHandler(protocol);\n return this;\n }\n\n async start() {\n await this.startAnnouncement();\n }\n\n async startAnnouncement() {\n if (this.isClosing) return;\n if (this.announceInterval.isRunning) {\n this.announceInterval.stop();\n }\n this.announcementStartedTime = Time.nowMs();\n this.announceInterval.start();\n await this.announce();\n }\n\n async expireAllFabricAnnouncements() {\n for (const broadcaster of this.broadcasters) {\n await broadcaster.expireAllAnnouncements();\n }\n }\n\n async announce(announceOnce = false) {\n if (!announceOnce) {\n // Stop announcement if duration is reached\n if (\n this.announcementStartedTime !== null &&\n Time.nowMs() - this.announcementStartedTime > DEVICE_ANNOUNCEMENT_DURATION_MS\n ) {\n await this.endCommissioning();\n logger.debug(\"Announcement duration reached, stop announcing\");\n return;\n }\n if (this.activeCommissioningMode !== AdministratorCommissioning.CommissioningWindowStatus.WindowNotOpen) {\n // Re-Announce but do not re-set Fabrics\n for (const broadcaster of this.broadcasters) {\n await broadcaster.announce();\n }\n return;\n }\n }\n const fabrics = this.#fabricManager.getFabrics();\n if (fabrics.length) {\n let fabricsWithoutSessions = 0;\n for (const fabric of fabrics) {\n const session = this.#sessionManager.getSessionForNode(fabric, fabric.rootNodeId);\n if (session === undefined || !session.isSecure || session.numberOfActiveSubscriptions === 0) {\n fabricsWithoutSessions++;\n logger.debug(\"Announcing\", Diagnostic.dict({ fabric: fabric.fabricId }));\n }\n }\n for (const broadcaster of this.broadcasters) {\n await broadcaster.setFabrics(fabrics);\n if (fabricsWithoutSessions > 0) {\n await broadcaster.announce();\n }\n }\n } else {\n // No fabric paired yet, so announce as \"ready for commissioning\"\n // And expire operational Fabric announcements (if fabric got just deleted)\n await this.expireAllFabricAnnouncements();\n await this.allowBasicCommissioning();\n }\n }\n\n private async announceAsCommissionable(\n mode: AdministratorCommissioning.CommissioningWindowStatus,\n activeCommissioningEndCallback?: () => void,\n discriminator?: number,\n ) {\n if (this.activeCommissioningMode !== AdministratorCommissioning.CommissioningWindowStatus.WindowNotOpen) {\n throw new InternalError(\n `Commissioning window already open with different mode (${this.activeCommissioningMode})!`,\n );\n }\n if (this.activeCommissioningEndCallback !== undefined) {\n throw new InternalError(\"Commissioning window already open with different callback!\");\n }\n this.activeCommissioningMode = mode;\n if (activeCommissioningEndCallback !== undefined) {\n this.activeCommissioningEndCallback = activeCommissioningEndCallback;\n }\n // MDNS is sent in parallel\n // TODO - untracked promise\n this.sendCommissionableAnnouncement(mode, discriminator).catch(error =>\n logger.warn(\"Error sending announcement\", error),\n );\n }\n\n async sendCommissionableAnnouncement(\n mode: AdministratorCommissioning.CommissioningWindowStatus,\n discriminator?: number,\n ) {\n const commissioningConfig = this.getCommissioningConfig();\n for (const broadcaster of this.broadcasters) {\n await broadcaster.setCommissionMode(\n mode === AdministratorCommissioning.CommissioningWindowStatus.EnhancedWindowOpen ? 2 : 1,\n {\n ...commissioningConfig.productDescription,\n discriminator: discriminator ?? commissioningConfig.discriminator,\n },\n );\n }\n await this.startAnnouncement();\n }\n\n async getNextAvailableSessionId() {\n return this.#sessionManager.getNextAvailableSessionId();\n }\n\n findFabricFromDestinationId(destinationId: ByteArray, peerRandom: ByteArray) {\n return this.#fabricManager.findFabricFromDestinationId(destinationId, peerRandom);\n }\n\n async sendFabricAnnouncements(fabrics: Fabric[], expireCommissioningAnnouncement = false) {\n for (const broadcaster of this.broadcasters) {\n await broadcaster.setFabrics(fabrics, expireCommissioningAnnouncement);\n await broadcaster.announce();\n }\n }\n\n getFabricByIndex(fabricIndex: FabricIndex) {\n return this.#fabricManager.getFabrics().find(fabric => fabric.fabricIndex === fabricIndex);\n }\n\n initiateExchange(fabric: Fabric, nodeId: NodeId, protocolId: number) {\n return this.exchangeManager.initiateExchange(fabric, nodeId, protocolId);\n }\n\n findResumptionRecordById(resumptionId: ByteArray) {\n return this.#sessionManager.findResumptionRecordById(resumptionId);\n }\n\n async saveResumptionRecord(resumptionRecord: ResumptionRecord) {\n return this.#sessionManager.saveResumptionRecord(resumptionRecord);\n }\n\n getFabrics() {\n return this.#fabricManager.getFabrics();\n }\n\n isCommissioned() {\n return !!this.#fabricManager.getFabrics().length;\n }\n\n async allowEnhancedCommissioning(\n discriminator: number,\n paseServer: PaseServer,\n commissioningEndCallback: () => void,\n ) {\n if (this.activeCommissioningMode === AdministratorCommissioning.CommissioningWindowStatus.BasicWindowOpen) {\n throw new MatterFlowError(\n \"Basic commissioning window is already open! Can not set Enhanced commissioning mode.\",\n );\n }\n\n this.secureChannelProtocol.setPaseCommissioner(paseServer);\n await this.announceAsCommissionable(\n AdministratorCommissioning.CommissioningWindowStatus.EnhancedWindowOpen,\n commissioningEndCallback,\n discriminator,\n );\n }\n\n async allowBasicCommissioning(commissioningEndCallback?: () => void) {\n if (this.activeCommissioningMode === AdministratorCommissioning.CommissioningWindowStatus.EnhancedWindowOpen) {\n throw new MatterFlowError(\n \"Enhanced commissioning window is already open! Can not set Basic commissioning mode.\",\n );\n }\n\n this.secureChannelProtocol.setPaseCommissioner(\n await PaseServer.fromPin(this.getCommissioningConfig().passcode, {\n iterations: 1000,\n salt: Crypto.get().getRandomData(32),\n }),\n );\n\n await this.announceAsCommissionable(\n AdministratorCommissioning.CommissioningWindowStatus.BasicWindowOpen,\n commissioningEndCallback,\n );\n }\n\n async endCommissioning() {\n logger.debug(\"Commissioning mode ended, stop announcements.\");\n // Remove PASE responder when we close enhanced commissioning window or node is commissioned\n if (\n this.activeCommissioningMode === AdministratorCommissioning.CommissioningWindowStatus.EnhancedWindowOpen ||\n this.isCommissioned()\n ) {\n this.secureChannelProtocol.removePaseCommissioner();\n }\n this.activeCommissioningMode = AdministratorCommissioning.CommissioningWindowStatus.WindowNotOpen;\n this.announceInterval.stop();\n this.announcementStartedTime = null;\n if (this.activeCommissioningEndCallback !== undefined) {\n const activeCommissioningEndCallback = this.activeCommissioningEndCallback;\n this.activeCommissioningEndCallback = undefined;\n activeCommissioningEndCallback();\n }\n for (const broadcaster of this.broadcasters) {\n await broadcaster.expireCommissioningAnnouncement();\n }\n logger.info(\"All announcements expired\");\n }\n\n existsOpenPaseSession() {\n return !!this.#sessionManager.getPaseSession();\n }\n\n async findDevice(\n fabric: Fabric,\n nodeId: NodeId,\n timeOutSeconds = 5,\n ): Promise<undefined | { session: Session<MatterDevice>; channel: Channel<ByteArray> }> {\n // TODO: return the first not undefined answer or undefined\n const device = await this.scanners[0].findOperationalDevice(fabric, nodeId, timeOutSeconds);\n if (device === undefined) return undefined;\n const session = this.#sessionManager.getSessionForNode(fabric, nodeId);\n if (session === undefined) return undefined;\n // TODO: have the interface and scanner linked\n const networkInterface = this.transportInterfaces.find(netInterface => isNetworkInterface(netInterface));\n if (networkInterface === undefined || !isNetworkInterface(networkInterface)) {\n throw new NetworkError(\"No network interface found\");\n } // TODO meeehhh\n return { session, channel: await networkInterface.openChannel(device.addresses[0]) };\n }\n\n async clearSubscriptionsForNode(peerNodeId: NodeId, flushSubscriptions?: boolean) {\n await this.#sessionManager.clearSubscriptionsForNode(peerNodeId, flushSubscriptions);\n }\n\n async close() {\n this.#isClosing = true;\n await this.endCommissioning();\n await this.#announcementMutex;\n for (const broadcaster of this.broadcasters) {\n await broadcaster.close();\n }\n if (this.#failsafeContext) {\n await this.#failsafeContext.close();\n this.#failsafeContext = undefined;\n }\n await this.exchangeManager.close();\n await this.#sessionManager.close();\n await this.channelManager.close();\n for (const transportInterface of this.transportInterfaces) {\n await transportInterface.close();\n }\n }\n\n getActiveSessionInformation() {\n return this.#sessionManager.getActiveSessionInformation();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -7,6 +7,7 @@ import { Mei } from "../../datatype/ManufacturerExtensibleIdentifier.js";
|
|
|
7
7
|
import { ElementTag } from "../definitions/index.js";
|
|
8
8
|
import { AttributeElement } from "../elements/index.js";
|
|
9
9
|
import { PropertyModel } from "./PropertyModel.js";
|
|
10
|
+
export declare const GLOBAL_IDS: Set<number>;
|
|
10
11
|
export declare class AttributeModel extends PropertyModel implements AttributeElement {
|
|
11
12
|
tag: AttributeElement.Tag;
|
|
12
13
|
id: Mei;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttributeModel.d.ts","sourceRoot":"","sources":["../../../../src/model/models/AttributeModel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,oDAAoD,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAW,MAAM,sBAAsB,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"AttributeModel.d.ts","sourceRoot":"","sources":["../../../../src/model/models/AttributeModel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,oDAAoD,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAW,MAAM,sBAAsB,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,eAAO,MAAM,UAAU,aAA4D,CAAC;AAQpF,qBAAa,cAAe,SAAQ,aAAc,YAAW,gBAAgB;IAChE,GAAG,EAAE,gBAAgB,CAAC,GAAG,CAAwB;IACjD,EAAE,EAAG,GAAG,CAAC;IAElB,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM;IAI1B,IAAa,iBAAiB,qBAI7B;IAED,IAAI,QAAQ,YAEX;IAED,IAAI,YAAY,YAEf;IAED,IAAI,KAAK,YAER;gBAEW,UAAU,EAAE,gBAAgB,CAAC,UAAU;IAQnD,MAAM,CAAC,GAAG,aAAwB;CACrC"}
|
|
@@ -7,6 +7,7 @@ import { ElementTag } from "../definitions/index.js";
|
|
|
7
7
|
import { AttributeElement, Globals } from "../elements/index.js";
|
|
8
8
|
import { Model } from "./Model.js";
|
|
9
9
|
import { PropertyModel } from "./PropertyModel.js";
|
|
10
|
+
const GLOBAL_IDS = /* @__PURE__ */ new Set([65533, 65532, 65531, 65530, 65529, 65528]);
|
|
10
11
|
const globalIds = /* @__PURE__ */ new Set();
|
|
11
12
|
for (const element of Object.values(Globals)) {
|
|
12
13
|
if (element.tag === ElementTag.Attribute) {
|
|
@@ -43,6 +44,7 @@ class AttributeModel extends PropertyModel {
|
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
export {
|
|
46
|
-
AttributeModel
|
|
47
|
+
AttributeModel,
|
|
48
|
+
GLOBAL_IDS
|
|
47
49
|
};
|
|
48
50
|
//# sourceMappingURL=AttributeModel.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/model/models/AttributeModel.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Mei } from \"../../datatype/ManufacturerExtensibleIdentifier.js\";\nimport { ElementTag } from \"../definitions/index.js\";\nimport { AttributeElement, Globals } from \"../elements/index.js\";\nimport { Model } from \"./Model.js\";\nimport { PropertyModel } from \"./PropertyModel.js\";\n\nconst globalIds = new Set<number>();\nfor (const element of Object.values(Globals)) {\n if (element.tag === ElementTag.Attribute) {\n globalIds.add(element.id);\n }\n}\n\nexport class AttributeModel extends PropertyModel implements AttributeElement {\n override tag: AttributeElement.Tag = AttributeElement.Tag;\n override id!: Mei;\n\n static isGlobal(id: number) {\n return globalIds.has(id);\n }\n\n override get isGlobalAttribute() {\n if (AttributeModel.isGlobal(this.id)) {\n return true;\n }\n }\n\n get writable() {\n return !this.fixed && this.effectiveAccess.writable;\n }\n\n get fabricScoped() {\n return !!this.effectiveAccess.fabric;\n }\n\n get fixed() {\n return !!this.effectiveQuality.fixed;\n }\n\n constructor(definition: AttributeElement.Properties) {\n super(definition);\n }\n\n static {\n Model.types[AttributeElement.Tag] = this;\n }\n\n static Tag = AttributeElement.Tag;\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB,eAAe;AAC1C,SAAS,aAAa;AACtB,SAAS,qBAAqB;
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Mei } from \"../../datatype/ManufacturerExtensibleIdentifier.js\";\nimport { ElementTag } from \"../definitions/index.js\";\nimport { AttributeElement, Globals } from \"../elements/index.js\";\nimport { Model } from \"./Model.js\";\nimport { PropertyModel } from \"./PropertyModel.js\";\n\n// Full set of global IDs per core spec 1.3\nexport const GLOBAL_IDS = new Set([0xfffd, 0xfffc, 0xfffb, 0xfffa, 0xfff9, 0xfff8]);\nconst globalIds = new Set<number>();\nfor (const element of Object.values(Globals)) {\n if (element.tag === ElementTag.Attribute) {\n globalIds.add(element.id);\n }\n}\n\nexport class AttributeModel extends PropertyModel implements AttributeElement {\n override tag: AttributeElement.Tag = AttributeElement.Tag;\n override id!: Mei;\n\n static isGlobal(id: number) {\n return globalIds.has(id);\n }\n\n override get isGlobalAttribute() {\n if (AttributeModel.isGlobal(this.id)) {\n return true;\n }\n }\n\n get writable() {\n return !this.fixed && this.effectiveAccess.writable;\n }\n\n get fabricScoped() {\n return !!this.effectiveAccess.fabric;\n }\n\n get fixed() {\n return !!this.effectiveQuality.fixed;\n }\n\n constructor(definition: AttributeElement.Properties) {\n super(definition);\n }\n\n static {\n Model.types[AttributeElement.Tag] = this;\n }\n\n static Tag = AttributeElement.Tag;\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB,eAAe;AAC1C,SAAS,aAAa;AACtB,SAAS,qBAAqB;AAGvB,MAAM,aAAa,oBAAI,IAAI,CAAC,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,KAAM,CAAC;AAClF,MAAM,YAAY,oBAAI,IAAY;AAClC,WAAW,WAAW,OAAO,OAAO,OAAO,GAAG;AAC1C,MAAI,QAAQ,QAAQ,WAAW,WAAW;AACtC,cAAU,IAAI,QAAQ,EAAE;AAAA,EAC5B;AACJ;AAEO,MAAM,uBAAuB,cAA0C;AAAA,EA0B1E,YAAY,YAAyC;AACjD,UAAM,UAAU;AA1BpB,SAAS,MAA4B,iBAAiB;AAAA,EA2BtD;AAAA,EAxBA,OAAO,SAAS,IAAY;AACxB,WAAO,UAAU,IAAI,EAAE;AAAA,EAC3B;AAAA,EAEA,IAAa,oBAAoB;AAC7B,QAAI,eAAe,SAAS,KAAK,EAAE,GAAG;AAClC,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EAEA,IAAI,WAAW;AACX,WAAO,CAAC,KAAK,SAAS,KAAK,gBAAgB;AAAA,EAC/C;AAAA,EAEA,IAAI,eAAe;AACf,WAAO,CAAC,CAAC,KAAK,gBAAgB;AAAA,EAClC;AAAA,EAEA,IAAI,QAAQ;AACR,WAAO,CAAC,CAAC,KAAK,iBAAiB;AAAA,EACnC;AAAA,EAMA,OAAO;AACH,UAAM,MAAM,iBAAiB,GAAG,IAAI;AAAA,EACxC;AAAA,EAEA;AAAA,SAAO,MAAM,iBAAiB;AAAA;AAClC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionalInteractionServer.d.ts","sourceRoot":"","sources":["../../../../src/node/server/TransactionalInteractionServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAMrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;
|
|
1
|
+
{"version":3,"file":"TransactionalInteractionServer.d.ts","sourceRoot":"","sources":["../../../../src/node/server/TransactionalInteractionServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAMrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;AAEvG,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAEtD,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAIxE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAE9E,OAAO,EAEH,YAAY,EACZ,aAAa,EAChB,MAAM,oDAAoD,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,mDAAmD,CAAC;AACnF,OAAO,EACH,aAAa,EACb,WAAW,EACX,SAAS,EACT,iBAAiB,EACpB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAY9C;;;;;;;;;;;GAWG;AACH,qBAAa,8BAA+B,SAAQ,iBAAiB;;gBASrD,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;IA8BjD,CAAC,MAAM,CAAC,YAAY,CAAC;IAM3B,gBAAgB;IAID,aAAa,CAAC,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC;IAiBpE,IAAI,SAAS,wBASZ;cAEwB,aAAa,CAClC,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,kBAAkB,CAAC,GAAG,CAAC,EAClC,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,cAAc,EAAE,OAAO,EACvB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB;;;;cAgBN,SAAS,CAC9B,IAAI,EAAE,SAAS,EACf,YAAY,EAAE,cAAc,CAAC,OAAO,cAAc,CAAC,EAAE,GAAG,SAAS,EACjE,KAAK,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,EAC5B,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,cAAc,EAAE,OAAO,EACvB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;IAsBpB,kBAAkB,CAC7B,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,OAAO,GACjB,OAAO,CAAC,aAAa,CAAC;cAWA,cAAc,CACnC,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,eAAe,CAAC,GAAG,CAAC,EAC/B,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,UAAQ,EACb,WAAW,CAAC,EAAE,OAAO;cA6BA,aAAa,CAClC,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EAChC,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,aAAa,EAAE,GAAG,EAClB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,UAAQ;;;;;;CAmCpB"}
|