@matterbridge/core 3.7.2-dev-20260330-bb55c39 → 3.7.2-dev-20260402-c12a10e
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/backendExpress.d.ts +18 -0
- package/dist/backendExpress.js +445 -0
- package/dist/backendWsServer.d.ts +35 -0
- package/dist/backendWsServer.js +307 -0
- package/dist/behaviors/doorLockServer.d.ts +36 -2
- package/dist/behaviors/doorLockServer.js +352 -6
- package/dist/behaviors/export.d.ts +0 -2
- package/dist/behaviors/export.js +0 -2
- package/dist/cli.js +2 -1
- package/dist/export.d.ts +0 -2
- package/dist/export.js +0 -2
- package/dist/frontend.d.ts +16 -9
- package/dist/frontend.js +52 -42
- package/dist/helpers.js +0 -5
- package/dist/jestutils/jestHelpers.d.ts +1 -1
- package/dist/jestutils/jestHelpers.js +19 -9
- package/dist/matterNode.js +18 -8
- package/dist/matterbridge.d.ts +0 -7
- package/dist/matterbridge.js +24 -52
- package/dist/matterbridgeEndpoint.d.ts +4 -5
- package/dist/matterbridgeEndpoint.js +9 -33
- package/dist/matterbridgeEndpointCommandHandler.d.ts +8 -2
- package/dist/matterbridgeEndpointCommandHandler.js +2 -1
- package/dist/pluginManager.d.ts +1 -0
- package/dist/pluginManager.js +14 -2
- package/package.json +5 -5
- package/dist/behaviors/pinDoorLockServer.d.ts +0 -32
- package/dist/behaviors/pinDoorLockServer.js +0 -168
- package/dist/behaviors/userPinDoorLockServer.d.ts +0 -57
- package/dist/behaviors/userPinDoorLockServer.js +0 -348
|
@@ -1,348 +0,0 @@
|
|
|
1
|
-
import { DoorLockServer } from '@matter/node/behaviors/door-lock';
|
|
2
|
-
import { DoorLock } from '@matter/types/clusters/door-lock';
|
|
3
|
-
import { StatusResponse } from '@matter/types/common';
|
|
4
|
-
import { FabricIndex } from '@matter/types/datatype';
|
|
5
|
-
import { Status } from '@matter/types/globals';
|
|
6
|
-
import { getEnumDescription } from '@matterbridge/utils';
|
|
7
|
-
import { debugStringify } from 'node-ansi-logger';
|
|
8
|
-
import { MatterbridgeServer } from './matterbridgeServer.js';
|
|
9
|
-
export class MatterbridgeUserPinDoorLockServer extends DoorLockServer.with(DoorLock.Feature.User, DoorLock.Feature.PinCredential, DoorLock.Feature.CredentialOverTheAirAccess).enable({
|
|
10
|
-
events: { doorLockAlarm: true, lockOperation: true, lockOperationError: true },
|
|
11
|
-
commands: { lockDoor: true, unlockDoor: true, unlockWithTimeout: true },
|
|
12
|
-
}) {
|
|
13
|
-
getAccessingFabricIndex() {
|
|
14
|
-
let fabricIndex;
|
|
15
|
-
try {
|
|
16
|
-
fabricIndex = this.context.fabric;
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
if (fabricIndex === undefined || fabricIndex === FabricIndex.NO_FABRIC) {
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
return fabricIndex;
|
|
25
|
-
}
|
|
26
|
-
findStoredCredential(credential) {
|
|
27
|
-
for (const user of this.internal.users) {
|
|
28
|
-
for (const storedCredential of user.credentials ?? []) {
|
|
29
|
-
if (storedCredential.credentialType === credential.credentialType && storedCredential.credentialIndex === credential.credentialIndex) {
|
|
30
|
-
return { user, storedCredential };
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
getStoredCredentialStateDebug() {
|
|
37
|
-
if (this.internal.users.length === 0) {
|
|
38
|
-
return 'no users';
|
|
39
|
-
}
|
|
40
|
-
return this.internal.users
|
|
41
|
-
.map((user) => {
|
|
42
|
-
const credentials = user.credentials
|
|
43
|
-
?.map((credential) => `${getEnumDescription(DoorLock.CredentialType, credential.credentialType)}:${credential.credentialIndex}=0x${Buffer.from(credential.credentialData).toString('hex')}`)
|
|
44
|
-
.join(', ') ?? 'none';
|
|
45
|
-
return `user ${user.userIndex} [${credentials}]`;
|
|
46
|
-
})
|
|
47
|
-
.join('; ');
|
|
48
|
-
}
|
|
49
|
-
logStoredCredentialState(reason) {
|
|
50
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
51
|
-
device.log.debug(`MatterbridgeDoorLockServer: ${reason}; stored credentials: ${this.getStoredCredentialStateDebug()}`);
|
|
52
|
-
}
|
|
53
|
-
hasMatchingPinCredential(pinCode) {
|
|
54
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
55
|
-
device.log.debug(`MatterbridgeDoorLockServer: checking remote PIN 0x${Buffer.from(pinCode).toString('hex')} against ${this.internal.users.length} user(s)`);
|
|
56
|
-
for (const user of this.internal.users) {
|
|
57
|
-
for (const storedCredential of user.credentials ?? []) {
|
|
58
|
-
if (storedCredential.credentialType !== DoorLock.CredentialType.Pin) {
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
if (Buffer.from(storedCredential.credentialData).equals(Buffer.from(pinCode))) {
|
|
62
|
-
device.log.debug(`MatterbridgeDoorLockServer: remote PIN matched userIndex ${user.userIndex} credentialIndex ${storedCredential.credentialIndex}`);
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
device.log.debug(`MatterbridgeDoorLockServer: remote PIN 0x${Buffer.from(pinCode).toString('hex')} did not match any stored PIN credential`);
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
validateRemotePinCode(pinCode) {
|
|
71
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
72
|
-
if (!this.state.requirePinForRemoteOperation) {
|
|
73
|
-
device.log.debug('MatterbridgeDoorLockServer: skipping remote PIN validation because requirePinForRemoteOperation is false');
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
if (pinCode === undefined) {
|
|
77
|
-
device.log.debug('MatterbridgeDoorLockServer: rejecting remote operation because the request did not include a PIN');
|
|
78
|
-
this.logStoredCredentialState('remote PIN validation failed');
|
|
79
|
-
throw new StatusResponse.FailureError('Missing or invalid PIN code for remote operation');
|
|
80
|
-
}
|
|
81
|
-
device.log.debug(`MatterbridgeDoorLockServer: validating remote PIN 0x${Buffer.from(pinCode).toString('hex')}`);
|
|
82
|
-
if (!this.hasMatchingPinCredential(pinCode)) {
|
|
83
|
-
this.logStoredCredentialState('remote PIN validation failed');
|
|
84
|
-
throw new StatusResponse.FailureError('Missing or invalid PIN code for remote operation');
|
|
85
|
-
}
|
|
86
|
-
device.log.debug(`MatterbridgeDoorLockServer: accepted remote PIN 0x${Buffer.from(pinCode).toString('hex')}`);
|
|
87
|
-
}
|
|
88
|
-
getNextOccupiedCredentialIndex(credential) {
|
|
89
|
-
let nextCredentialIndex = null;
|
|
90
|
-
for (const user of this.internal.users) {
|
|
91
|
-
for (const storedCredential of user.credentials ?? []) {
|
|
92
|
-
if (storedCredential.credentialType !== credential.credentialType || storedCredential.credentialIndex <= credential.credentialIndex) {
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
if (nextCredentialIndex === null || storedCredential.credentialIndex < nextCredentialIndex) {
|
|
96
|
-
nextCredentialIndex = storedCredential.credentialIndex;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return nextCredentialIndex;
|
|
101
|
-
}
|
|
102
|
-
upsertStoredCredential(userIndex, credential, credentialData) {
|
|
103
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
104
|
-
if (userIndex === null) {
|
|
105
|
-
device.log.debug(`MatterbridgeDoorLockServer: not storing credentialType ${getEnumDescription(DoorLock.CredentialType, credential.credentialType)} credentialIndex ${credential.credentialIndex} because userIndex is null`);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
const user = this.internal.users.find((storedUser) => storedUser.userIndex === userIndex);
|
|
109
|
-
if (!user) {
|
|
110
|
-
device.log.debug(`MatterbridgeDoorLockServer: not storing credentialType ${getEnumDescription(DoorLock.CredentialType, credential.credentialType)} credentialIndex ${credential.credentialIndex} because userIndex ${userIndex} was not found`);
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
let removedCredentials = 0;
|
|
114
|
-
for (const storedUser of this.internal.users) {
|
|
115
|
-
const nextCredentials = storedUser.credentials?.filter((storedCredential) => storedCredential.credentialType !== credential.credentialType || storedCredential.credentialIndex !== credential.credentialIndex) ?? null;
|
|
116
|
-
removedCredentials += (storedUser.credentials?.length ?? 0) - (nextCredentials?.length ?? 0);
|
|
117
|
-
storedUser.credentials = nextCredentials && nextCredentials.length > 0 ? nextCredentials : null;
|
|
118
|
-
}
|
|
119
|
-
if (!user.credentials) {
|
|
120
|
-
user.credentials = [];
|
|
121
|
-
}
|
|
122
|
-
user.credentials.push({
|
|
123
|
-
credentialType: credential.credentialType,
|
|
124
|
-
credentialIndex: credential.credentialIndex,
|
|
125
|
-
credentialData: Uint8Array.from(credentialData),
|
|
126
|
-
});
|
|
127
|
-
device.log.debug(`MatterbridgeDoorLockServer: stored credentialType ${getEnumDescription(DoorLock.CredentialType, credential.credentialType)} credentialIndex ${credential.credentialIndex} for userIndex ${userIndex} (removed ${removedCredentials} replaced credential(s))`);
|
|
128
|
-
this.logStoredCredentialState('credential stored');
|
|
129
|
-
}
|
|
130
|
-
clearStoredCredential(credential) {
|
|
131
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
132
|
-
for (const user of this.internal.users) {
|
|
133
|
-
if (credential === null) {
|
|
134
|
-
user.credentials = null;
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
const nextCredentials = user.credentials?.filter((storedCredential) => storedCredential.credentialType !== credential.credentialType || storedCredential.credentialIndex !== credential.credentialIndex) ?? null;
|
|
138
|
-
user.credentials = nextCredentials && nextCredentials.length > 0 ? nextCredentials : null;
|
|
139
|
-
}
|
|
140
|
-
device.log.debug(`MatterbridgeDoorLockServer: cleared ${credential ? `${getEnumDescription(DoorLock.CredentialType, credential.credentialType)} credentialIndex ${credential.credentialIndex}` : 'all credentials'} from internal state`);
|
|
141
|
-
this.logStoredCredentialState('credential cleared');
|
|
142
|
-
}
|
|
143
|
-
async lockDoor(request) {
|
|
144
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
145
|
-
device.log.info(`Locking door with pincode ${request.pinCode ? '0x' + Buffer.from(request.pinCode).toString('hex') : 'N/A'} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
146
|
-
this.validateRemotePinCode(request.pinCode);
|
|
147
|
-
device.log.debug(`MatterbridgeDoorLockServer: remote lockDoor PIN validation completed`);
|
|
148
|
-
await device.commandHandler.executeHandler('DoorLock.lockDoor', {
|
|
149
|
-
command: 'lockDoor',
|
|
150
|
-
request,
|
|
151
|
-
cluster: DoorLockServer.id,
|
|
152
|
-
attributes: this.state,
|
|
153
|
-
endpoint: this.endpoint,
|
|
154
|
-
context: this.context,
|
|
155
|
-
});
|
|
156
|
-
device.log.debug(`MatterbridgeDoorLockServer: lockDoor called`);
|
|
157
|
-
await super.lockDoor(request);
|
|
158
|
-
}
|
|
159
|
-
async unlockDoor(request) {
|
|
160
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
161
|
-
device.log.info(`Unlocking door with pincode ${request.pinCode ? '0x' + Buffer.from(request.pinCode).toString('hex') : 'N/A'} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
162
|
-
this.validateRemotePinCode(request.pinCode);
|
|
163
|
-
device.log.debug(`MatterbridgeDoorLockServer: remote unlockDoor PIN validation completed`);
|
|
164
|
-
await device.commandHandler.executeHandler('DoorLock.unlockDoor', {
|
|
165
|
-
command: 'unlockDoor',
|
|
166
|
-
request,
|
|
167
|
-
cluster: DoorLockServer.id,
|
|
168
|
-
attributes: this.state,
|
|
169
|
-
endpoint: this.endpoint,
|
|
170
|
-
context: this.context,
|
|
171
|
-
});
|
|
172
|
-
device.log.debug(`MatterbridgeDoorLockServer: unlockDoor called`);
|
|
173
|
-
await super.unlockDoor(request);
|
|
174
|
-
}
|
|
175
|
-
async unlockWithTimeout(request) {
|
|
176
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
177
|
-
device.log.info(`Unlocking door with pincode ${request.pinCode ? '0x' + Buffer.from(request.pinCode).toString('hex') : 'N/A'} timeout ${request.timeout} seconds (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
178
|
-
this.validateRemotePinCode(request.pinCode);
|
|
179
|
-
device.log.debug(`MatterbridgeDoorLockServer: remote unlockWithTimeout PIN validation completed`);
|
|
180
|
-
await device.commandHandler.executeHandler('DoorLock.unlockWithTimeout', {
|
|
181
|
-
command: 'unlockWithTimeout',
|
|
182
|
-
request,
|
|
183
|
-
cluster: DoorLockServer.id,
|
|
184
|
-
attributes: this.state,
|
|
185
|
-
endpoint: this.endpoint,
|
|
186
|
-
context: this.context,
|
|
187
|
-
});
|
|
188
|
-
device.log.debug(`MatterbridgeDoorLockServer: unlockWithTimeout called`);
|
|
189
|
-
this.state.lockState = DoorLock.LockState.Unlocked;
|
|
190
|
-
}
|
|
191
|
-
async setUser(request) {
|
|
192
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
193
|
-
const accessingFabricIndex = this.getAccessingFabricIndex();
|
|
194
|
-
device.log.info(`Setting user operationType ${getEnumDescription(DoorLock.DataOperationType, request.operationType)} userIndex ${request.userIndex} userName ${request.userName ?? 'null'} userUniqueId ${request.userUniqueId ?? 'null'} userStatus ${getEnumDescription(DoorLock.UserStatus, request.userStatus, { fallback: 'null' })} userType ${getEnumDescription(DoorLock.UserType, request.userType, { fallback: 'null' })} credentialRule ${getEnumDescription(DoorLock.CredentialRule, request.credentialRule, { fallback: 'null' })} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
195
|
-
device.log.debug(`MatterbridgeDoorLockServer: setUser accessingFabricIndex ${accessingFabricIndex ?? 'null'}`);
|
|
196
|
-
await device.commandHandler.executeHandler('DoorLock.setUser', {
|
|
197
|
-
command: 'setUser',
|
|
198
|
-
request,
|
|
199
|
-
cluster: DoorLockServer.id,
|
|
200
|
-
attributes: this.state,
|
|
201
|
-
endpoint: this.endpoint,
|
|
202
|
-
context: this.context,
|
|
203
|
-
});
|
|
204
|
-
const user = this.internal.users.find((storedUser) => storedUser.userIndex === request.userIndex);
|
|
205
|
-
device.log.debug(`MatterbridgeDoorLockServer: setUser called for userIndex ${request.userIndex} (${user ? 'existing user ' + debugStringify(user) : 'new user'})`);
|
|
206
|
-
if (!user && request.operationType === DoorLock.DataOperationType.Add) {
|
|
207
|
-
this.internal.users.push({
|
|
208
|
-
userIndex: request.userIndex,
|
|
209
|
-
userName: request.userName,
|
|
210
|
-
userUniqueId: request.userUniqueId,
|
|
211
|
-
userStatus: request.userStatus,
|
|
212
|
-
userType: request.userType,
|
|
213
|
-
credentialRule: request.credentialRule,
|
|
214
|
-
credentials: null,
|
|
215
|
-
creatorFabricIndex: accessingFabricIndex,
|
|
216
|
-
lastModifiedFabricIndex: accessingFabricIndex,
|
|
217
|
-
nextUserIndex: null,
|
|
218
|
-
});
|
|
219
|
-
device.log.debug(`MatterbridgeDoorLockServer: added userIndex ${request.userIndex} (total users: ${this.internal.users.length}) to internal state: ${debugStringify(this.internal.users.find((storedUser) => storedUser.userIndex === request.userIndex))}`);
|
|
220
|
-
this.logStoredCredentialState('user added');
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
this.logStoredCredentialState(`setUser completed for userIndex ${request.userIndex} without adding a new internal user`);
|
|
224
|
-
}
|
|
225
|
-
async getUser(request) {
|
|
226
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
227
|
-
device.log.info(`Getting userIndex ${request.userIndex} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
228
|
-
await device.commandHandler.executeHandler('DoorLock.getUser', {
|
|
229
|
-
command: 'getUser',
|
|
230
|
-
request,
|
|
231
|
-
cluster: DoorLockServer.id,
|
|
232
|
-
attributes: this.state,
|
|
233
|
-
endpoint: this.endpoint,
|
|
234
|
-
context: this.context,
|
|
235
|
-
});
|
|
236
|
-
const user = this.internal.users.find((storedUser) => storedUser.userIndex === request.userIndex);
|
|
237
|
-
device.log.debug(`MatterbridgeDoorLockServer: getUser called for userIndex ${request.userIndex} (total users: ${this.internal.users.length}) (${user ? 'existing user: ' + debugStringify(user) : 'new user'})`);
|
|
238
|
-
this.logStoredCredentialState(`getUser returning state for userIndex ${request.userIndex}`);
|
|
239
|
-
if (user) {
|
|
240
|
-
return {
|
|
241
|
-
...user,
|
|
242
|
-
credentials: user.credentials?.map(({ credentialType, credentialIndex }) => ({ credentialType, credentialIndex })) ?? null,
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
return {
|
|
246
|
-
userIndex: request.userIndex,
|
|
247
|
-
userName: null,
|
|
248
|
-
userUniqueId: null,
|
|
249
|
-
userStatus: null,
|
|
250
|
-
userType: null,
|
|
251
|
-
credentialRule: null,
|
|
252
|
-
credentials: null,
|
|
253
|
-
creatorFabricIndex: null,
|
|
254
|
-
lastModifiedFabricIndex: null,
|
|
255
|
-
nextUserIndex: null,
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
async clearUser(request) {
|
|
259
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
260
|
-
device.log.info(`Clearing userIndex ${request.userIndex} ${request.userIndex === 0xfffe ? '(all users)' : ''} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
261
|
-
await device.commandHandler.executeHandler('DoorLock.clearUser', {
|
|
262
|
-
command: 'clearUser',
|
|
263
|
-
request,
|
|
264
|
-
cluster: DoorLockServer.id,
|
|
265
|
-
attributes: this.state,
|
|
266
|
-
endpoint: this.endpoint,
|
|
267
|
-
context: this.context,
|
|
268
|
-
});
|
|
269
|
-
device.log.debug(`MatterbridgeDoorLockServer: clearUser called for userIndex ${request.userIndex}`);
|
|
270
|
-
this.logStoredCredentialState(`clearUser completed for userIndex ${request.userIndex}`);
|
|
271
|
-
}
|
|
272
|
-
async setCredential(request) {
|
|
273
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
274
|
-
const accessingFabricIndex = this.getAccessingFabricIndex();
|
|
275
|
-
device.log.info(`Setting credential operationType ${getEnumDescription(DoorLock.DataOperationType, request.operationType)} credentialType ${getEnumDescription(DoorLock.CredentialType, request.credential.credentialType)} credentialIndex ${request.credential.credentialIndex} credentialData ${Buffer.from(request.credentialData).toString('hex') ? '0x' + Buffer.from(request.credentialData).toString('hex') : '0x'} userIndex ${request.userIndex ?? 'null'} userStatus ${getEnumDescription(DoorLock.UserStatus, request.userStatus, { fallback: 'null' })} userType ${getEnumDescription(DoorLock.UserType, request.userType, { fallback: 'null' })} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
276
|
-
await device.commandHandler.executeHandler('DoorLock.setCredential', {
|
|
277
|
-
command: 'setCredential',
|
|
278
|
-
request,
|
|
279
|
-
cluster: DoorLockServer.id,
|
|
280
|
-
attributes: this.state,
|
|
281
|
-
endpoint: this.endpoint,
|
|
282
|
-
context: this.context,
|
|
283
|
-
});
|
|
284
|
-
const user = this.internal.users.find((storedUser) => storedUser.userIndex === request.userIndex);
|
|
285
|
-
const existingCredential = this.findStoredCredential(request.credential);
|
|
286
|
-
device.log.debug(`MatterbridgeDoorLockServer: setCredential pre-update lookup for credentialIndex ${request.credential.credentialIndex} (${existingCredential ? 'existing credential found' : 'no existing credential'})`);
|
|
287
|
-
device.log.debug(`MatterbridgeDoorLockServer: setCredential called for credentialIndex ${request.credential.credentialIndex}`);
|
|
288
|
-
if (user && (request.operationType === DoorLock.DataOperationType.Add || request.operationType === DoorLock.DataOperationType.Modify)) {
|
|
289
|
-
this.upsertStoredCredential(request.userIndex, request.credential, request.credentialData);
|
|
290
|
-
user.lastModifiedFabricIndex = accessingFabricIndex;
|
|
291
|
-
device.log.debug(`MatterbridgeDoorLockServer: setCredential updated lastModifiedFabricIndex for userIndex ${user.userIndex} to ${accessingFabricIndex ?? 'null'}`);
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
device.log.debug(`MatterbridgeDoorLockServer: setCredential did not update internal state for credentialIndex ${request.credential.credentialIndex} (user ${request.userIndex ?? 'null'} not found or operation not handled)`);
|
|
295
|
-
}
|
|
296
|
-
return {
|
|
297
|
-
status: Status.Success,
|
|
298
|
-
userIndex: request.userIndex,
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
async getCredentialStatus(request) {
|
|
302
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
303
|
-
device.log.info(`Getting credential status for credentialType ${getEnumDescription(DoorLock.CredentialType, request.credential.credentialType)} credentialIndex ${request.credential.credentialIndex} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
304
|
-
await device.commandHandler.executeHandler('DoorLock.getCredentialStatus', {
|
|
305
|
-
command: 'getCredentialStatus',
|
|
306
|
-
request,
|
|
307
|
-
cluster: DoorLockServer.id,
|
|
308
|
-
attributes: this.state,
|
|
309
|
-
endpoint: this.endpoint,
|
|
310
|
-
context: this.context,
|
|
311
|
-
});
|
|
312
|
-
const credentialRecord = this.findStoredCredential(request.credential);
|
|
313
|
-
const nextCredentialIndex = this.getNextOccupiedCredentialIndex(request.credential);
|
|
314
|
-
device.log.debug(`MatterbridgeDoorLockServer: getCredentialStatus called`);
|
|
315
|
-
device.log.debug(`MatterbridgeDoorLockServer: getCredentialStatus result for credentialIndex ${request.credential.credentialIndex} (${credentialRecord ? `userIndex ${credentialRecord.user.userIndex} credentialData 0x${Buffer.from(credentialRecord.storedCredential.credentialData).toString('hex')}` : 'credential missing'}, nextCredentialIndex ${nextCredentialIndex ?? 'null'})`);
|
|
316
|
-
return {
|
|
317
|
-
credentialExists: credentialRecord !== null,
|
|
318
|
-
userIndex: credentialRecord?.user.userIndex ?? null,
|
|
319
|
-
creatorFabricIndex: credentialRecord?.user.creatorFabricIndex ?? null,
|
|
320
|
-
lastModifiedFabricIndex: credentialRecord?.user.lastModifiedFabricIndex ?? null,
|
|
321
|
-
nextCredentialIndex,
|
|
322
|
-
credentialData: credentialRecord?.storedCredential.credentialData ?? null,
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
async clearCredential(request) {
|
|
326
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
327
|
-
device.log.info(`Clearing credentialType ${request.credential ? getEnumDescription(DoorLock.CredentialType, request.credential.credentialType) : 'null'} credentialIndex ${request.credential ? request.credential.credentialIndex : 'null'} ${request.credential === null ? '(all credentials)' : ''} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
328
|
-
await device.commandHandler.executeHandler('DoorLock.clearCredential', {
|
|
329
|
-
command: 'clearCredential',
|
|
330
|
-
request,
|
|
331
|
-
cluster: DoorLockServer.id,
|
|
332
|
-
attributes: this.state,
|
|
333
|
-
endpoint: this.endpoint,
|
|
334
|
-
context: this.context,
|
|
335
|
-
});
|
|
336
|
-
this.clearStoredCredential(request.credential);
|
|
337
|
-
device.log.debug('MatterbridgeDoorLockServer: clearCredential called');
|
|
338
|
-
this.logStoredCredentialState(`clearCredential completed for ${request.credential
|
|
339
|
-
? `${getEnumDescription(DoorLock.CredentialType, request.credential.credentialType)} credentialIndex ${request.credential.credentialIndex}`
|
|
340
|
-
: 'all credentials'}`);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
(function (MatterbridgeUserPinDoorLockServer) {
|
|
344
|
-
class Internal {
|
|
345
|
-
users = [];
|
|
346
|
-
}
|
|
347
|
-
MatterbridgeUserPinDoorLockServer.Internal = Internal;
|
|
348
|
-
})(MatterbridgeUserPinDoorLockServer || (MatterbridgeUserPinDoorLockServer = {}));
|