sesame-kit 0.4.0
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/LICENSE +26 -0
- package/LICENSE.biz3 +21 -0
- package/README.ja.md +225 -0
- package/README.md +222 -0
- package/bin/sesame.js +8 -0
- package/clients/js/sesame-client.mjs +208 -0
- package/clients/python/pyproject.toml +5 -0
- package/clients/python/sesame_client.py +323 -0
- package/clients/python/setup.cfg +11 -0
- package/docs/architecture.ja.md +132 -0
- package/docs/architecture.md +105 -0
- package/docs/commands.ja.md +316 -0
- package/docs/commands.md +308 -0
- package/docs/library.ja.md +152 -0
- package/docs/library.md +152 -0
- package/docs/migration.ja.md +13 -0
- package/docs/migration.md +13 -0
- package/package.json +114 -0
- package/src/access.js +375 -0
- package/src/account.js +36 -0
- package/src/auth.js +248 -0
- package/src/ble/devicemodel.js +164 -0
- package/src/ble/index.js +185 -0
- package/src/ble/protocol.js +319 -0
- package/src/ble/session.js +235 -0
- package/src/ble/transport.js +279 -0
- package/src/cli/access.js +373 -0
- package/src/cli/company.js +104 -0
- package/src/cli/iot.js +400 -0
- package/src/cli/org.js +788 -0
- package/src/cli/presetir.js +188 -0
- package/src/cli/schedule.js +83 -0
- package/src/cli/serve.js +308 -0
- package/src/cli.js +1815 -0
- package/src/client.js +957 -0
- package/src/company.js +147 -0
- package/src/config.js +575 -0
- package/src/crypto.js +162 -0
- package/src/devices.js +228 -0
- package/src/index.js +55 -0
- package/src/iot.js +513 -0
- package/src/ir.js +341 -0
- package/src/itemcodes.js +29 -0
- package/src/lock.js +194 -0
- package/src/org.js +803 -0
- package/src/paths.js +30 -0
- package/src/presetir.js +525 -0
- package/src/prompts.js +74 -0
- package/src/schedule.js +108 -0
- package/src/serve/daemon.js +251 -0
- package/src/serve/framing/grpc.js +145 -0
- package/src/serve/framing/http.js +144 -0
- package/src/serve/framing/ndjson.js +75 -0
- package/src/serve/framing/socket.js +73 -0
- package/src/serve/framing/stdio.js +28 -0
- package/src/serve/framing/token.js +36 -0
- package/src/serve/framing/ws.js +56 -0
- package/src/serve/grpc-methods.generated.json +378 -0
- package/src/serve/jsonrpc.js +164 -0
- package/src/serve/registry.js +226 -0
- package/src/serve/rpc-params.generated.json +1746 -0
- package/src/serve/sesame.proto +470 -0
- package/src/session-ui.js +181 -0
- package/src/sharekey.js +130 -0
- package/src/tokens.js +53 -0
- package/src/transport.js +634 -0
- package/src/util.js +26 -0
- package/types/access.d.ts +193 -0
- package/types/access.d.ts.map +1 -0
- package/types/account.d.ts +13 -0
- package/types/account.d.ts.map +1 -0
- package/types/auth.d.ts +80 -0
- package/types/auth.d.ts.map +1 -0
- package/types/ble/devicemodel.d.ts +212 -0
- package/types/ble/devicemodel.d.ts.map +1 -0
- package/types/ble/index.d.ts +160 -0
- package/types/ble/index.d.ts.map +1 -0
- package/types/ble/protocol.d.ts +201 -0
- package/types/ble/protocol.d.ts.map +1 -0
- package/types/ble/session.d.ts +129 -0
- package/types/ble/session.d.ts.map +1 -0
- package/types/ble/transport.d.ts +67 -0
- package/types/ble/transport.d.ts.map +1 -0
- package/types/cli/access.d.ts +6 -0
- package/types/cli/access.d.ts.map +1 -0
- package/types/cli/company.d.ts +6 -0
- package/types/cli/company.d.ts.map +1 -0
- package/types/cli/iot.d.ts +6 -0
- package/types/cli/iot.d.ts.map +1 -0
- package/types/cli/org.d.ts +6 -0
- package/types/cli/org.d.ts.map +1 -0
- package/types/cli/presetir.d.ts +6 -0
- package/types/cli/presetir.d.ts.map +1 -0
- package/types/cli/schedule.d.ts +6 -0
- package/types/cli/schedule.d.ts.map +1 -0
- package/types/cli/serve.d.ts +2 -0
- package/types/cli/serve.d.ts.map +1 -0
- package/types/cli.d.ts +2 -0
- package/types/cli.d.ts.map +1 -0
- package/types/client.d.ts +463 -0
- package/types/client.d.ts.map +1 -0
- package/types/company.d.ts +94 -0
- package/types/company.d.ts.map +1 -0
- package/types/config.d.ts +111 -0
- package/types/config.d.ts.map +1 -0
- package/types/crypto.d.ts +61 -0
- package/types/crypto.d.ts.map +1 -0
- package/types/devices.d.ts +116 -0
- package/types/devices.d.ts.map +1 -0
- package/types/index.d.ts +23 -0
- package/types/index.d.ts.map +1 -0
- package/types/iot.d.ts +312 -0
- package/types/iot.d.ts.map +1 -0
- package/types/ir.d.ts +147 -0
- package/types/ir.d.ts.map +1 -0
- package/types/itemcodes.d.ts +21 -0
- package/types/itemcodes.d.ts.map +1 -0
- package/types/lock.d.ts +89 -0
- package/types/lock.d.ts.map +1 -0
- package/types/org.d.ts +468 -0
- package/types/org.d.ts.map +1 -0
- package/types/paths.d.ts +10 -0
- package/types/paths.d.ts.map +1 -0
- package/types/presetir.d.ts +286 -0
- package/types/presetir.d.ts.map +1 -0
- package/types/prompts.d.ts +39 -0
- package/types/prompts.d.ts.map +1 -0
- package/types/schedule.d.ts +71 -0
- package/types/schedule.d.ts.map +1 -0
- package/types/serve/daemon.d.ts +133 -0
- package/types/serve/daemon.d.ts.map +1 -0
- package/types/serve/framing/grpc.d.ts +14 -0
- package/types/serve/framing/grpc.d.ts.map +1 -0
- package/types/serve/framing/http.d.ts +14 -0
- package/types/serve/framing/http.d.ts.map +1 -0
- package/types/serve/framing/ndjson.d.ts +19 -0
- package/types/serve/framing/ndjson.d.ts.map +1 -0
- package/types/serve/framing/socket.d.ts +14 -0
- package/types/serve/framing/socket.d.ts.map +1 -0
- package/types/serve/framing/stdio.d.ts +11 -0
- package/types/serve/framing/stdio.d.ts.map +1 -0
- package/types/serve/framing/token.d.ts +11 -0
- package/types/serve/framing/token.d.ts.map +1 -0
- package/types/serve/framing/ws.d.ts +13 -0
- package/types/serve/framing/ws.d.ts.map +1 -0
- package/types/serve/jsonrpc.d.ts +118 -0
- package/types/serve/jsonrpc.d.ts.map +1 -0
- package/types/serve/registry.d.ts +41 -0
- package/types/serve/registry.d.ts.map +1 -0
- package/types/session-ui.d.ts +36 -0
- package/types/session-ui.d.ts.map +1 -0
- package/types/sharekey.d.ts +35 -0
- package/types/sharekey.d.ts.map +1 -0
- package/types/tokens.d.ts +20 -0
- package/types/tokens.d.ts.map +1 -0
- package/types/transport.d.ts +138 -0
- package/types/transport.d.ts.map +1 -0
- package/types/util.d.ts +20 -0
- package/types/util.d.ts.map +1 -0
- package/vendor/biz3/README.md +37 -0
- package/vendor/biz3/constants/cmdCode.d.ts +48 -0
- package/vendor/biz3/constants/cmdCode.d.ts.map +1 -0
- package/vendor/biz3/constants/cmdCode.js +92 -0
- package/vendor/biz3/constants/messageConstants.d.ts +28 -0
- package/vendor/biz3/constants/messageConstants.d.ts.map +1 -0
- package/vendor/biz3/constants/messageConstants.js +30 -0
- package/vendor/biz3/constants/sesameDeviceModel.d.ts +75 -0
- package/vendor/biz3/constants/sesameDeviceModel.d.ts.map +1 -0
- package/vendor/biz3/constants/sesameDeviceModel.js +77 -0
- package/vendor/biz3/package.json +5 -0
package/src/org.js
ADDED
|
@@ -0,0 +1,803 @@
|
|
|
1
|
+
// SESAME 組織管理 (employee / employeeGroup / role / deviceGroup / employeeDevice)。
|
|
2
|
+
//
|
|
3
|
+
// Ported from biz3 (CANDY-HOUSE/biz3, MIT):
|
|
4
|
+
// - vendor reference: references_web/src/api/useManageEmployee.js (employee / employeeGroup / role)
|
|
5
|
+
// - vendor reference: references_web/src/api/useManageGroup.js (deviceGroup / employeeDevice / getDeviceEmployeeKeys)
|
|
6
|
+
//
|
|
7
|
+
// これは「認証」ではなく「ログイン済みセッションで投げる組織管理 op」群。
|
|
8
|
+
// 認証フロー (Cognito / refresh / DEVICE_KEY) は auth.js のまま。ここは一切関与しない。
|
|
9
|
+
//
|
|
10
|
+
// ───────────── frame に関する一次資料の事実 (biz3 を 1 行ずつ確認済) ─────────────
|
|
11
|
+
//
|
|
12
|
+
// WebSocketManager.sendMessage は JSON.stringify(message) をそのまま ws.send するだけで
|
|
13
|
+
// (WebSocketManager.ts:383)、binary packing / checksum / UUID 変換 / topic 構築は一切ない。
|
|
14
|
+
// よって frame = 渡した JS オブジェクトそのもの。
|
|
15
|
+
//
|
|
16
|
+
// 応答ルーティングの 2 種類:
|
|
17
|
+
// (1) 同期応答 (op が送信 op と一致): biz3 は registerCallback(action, op, cb) で受ける。
|
|
18
|
+
// → CLI では client.request(frame) (action+op 一致を 1 件待つ) で対応。
|
|
19
|
+
// (2) 別 op の async push で返る一覧:
|
|
20
|
+
// - employee get → push op 'pubEmployees' (useManageEmployee.js:7,70-88)。
|
|
21
|
+
// - employee queryByCS → push op 'pubQueryByCS' (useManageEmployee.js:391-416)。
|
|
22
|
+
// どちらも page 単位で複数 chunk が届くので subscribe で蓄積する。
|
|
23
|
+
//
|
|
24
|
+
// フィールドのネスト差異 (op ごとに違う。biz3 を直接確認):
|
|
25
|
+
// employee: get=companyID 直置き / add,delete,order=items 直置き(companyID は item 内)
|
|
26
|
+
// / update=obj:{companyID,...} ラップ / queryByCS=keyword / confirmQueryByCS=email
|
|
27
|
+
// / currentInfo=引数なし。
|
|
28
|
+
// employeeGroup: getGroups=cid 直置き / add,update=obj:{cid,...} / deleteGroups=objs(配列)+cid
|
|
29
|
+
// / getBindDeviceGroup=gid のみ(cid を送らない!) / addBindUser,removeBindUser=cid,gid,uuids,items 直置き
|
|
30
|
+
// / removeBindDeviceGroup=cid+...data 直置き。
|
|
31
|
+
// role: get=companyID / post,delete=companyID+...data 直置き (cid ではなく companyID)。
|
|
32
|
+
// deviceGroup: getGroups=cid / add=obj:{name,cid,uuids} / update=obj:{cid,...item}
|
|
33
|
+
// / deleteGroups=objs(各要素に cid マージ) / addBindDevice,removeBindDevice=cid,gid,uuids,items 直置き
|
|
34
|
+
// / getBindUserGroup=gid のみ(cid 無し) / removeBindUserGroup=cid+...data 直置き。
|
|
35
|
+
// employeeDevice: add=items 直置き(companyID 無し) / group=...item+companyID 直置き
|
|
36
|
+
// / get=subUUID のみ / del,updateGuestTag,generateGuestQR=...data 直置き(companyID 無し)。
|
|
37
|
+
// getDeviceEmployeeKeys: deviceUUID+companyID+limit 直置き。
|
|
38
|
+
|
|
39
|
+
import { ACTION_TYPES } from "../vendor/biz3/constants/messageConstants.js";
|
|
40
|
+
import { assertSuccess } from "./util.js";
|
|
41
|
+
|
|
42
|
+
// action 文字列は vendor (biz3 messageConstants) から引く (手書きしない)。
|
|
43
|
+
const ACT_EMPLOYEE = ACTION_TYPES.BIZ3_MANAGE_EMPLOYEE; // "biz3ManageEmployee"
|
|
44
|
+
const ACT_EMPLOYEE_GROUP = ACTION_TYPES.BIZ3_MANAGE_EMPLOYEE_GROUP; // "biz3ManageEmployeeGroup"
|
|
45
|
+
const ACT_ROLE = ACTION_TYPES.BIZ3_MANAGE_ROLE; // "biz3ManageRole"
|
|
46
|
+
const ACT_DEVICE_GROUP = ACTION_TYPES.BIZ3_MANAGE_DEVICE_GROUP; // "biz3ManageDeviceGroup"
|
|
47
|
+
const ACT_EMPLOYEE_DEVICE = ACTION_TYPES.BIZ3_MANAGE_EMPLOYEE_DEVICE; // "biz3ManageEmployeeDevice"
|
|
48
|
+
const ACT_DEVICE_EMP_KEYS = ACTION_TYPES.BIZ3_GET_DEVICEEMOLOYEEKEYS; // "biz3GetDeviceEmployeeKeys"
|
|
49
|
+
|
|
50
|
+
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
51
|
+
|
|
52
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
53
|
+
// employee (biz3ManageEmployee)
|
|
54
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 社員一覧を取得する。
|
|
58
|
+
*
|
|
59
|
+
* biz3: get は ack のみで、実データは別 op 'pubEmployees' で page 単位に push される
|
|
60
|
+
* (useManageEmployee.js:7,18-22,70-88)。各 push の data 形:
|
|
61
|
+
* message.data = { totalCount, data: { list, page } }
|
|
62
|
+
* page===1 で全置換、page>1 で追記。本実装は totalCount と蓄積件数が一致するまで
|
|
63
|
+
* (または次 chunk が来なくなるまで) 待ち、全 list を 1 配列で返す。
|
|
64
|
+
*
|
|
65
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
66
|
+
* @param {{companyID:string, timeoutMs?:number}} params
|
|
67
|
+
* @returns {Promise<{count:number, list:any[]}>} count=totalCount, list=全社員
|
|
68
|
+
*/
|
|
69
|
+
export async function getEmployees(client, { companyID, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
70
|
+
if (!companyID) throw new Error("companyID required");
|
|
71
|
+
return collectChunks(client, {
|
|
72
|
+
action: ACT_EMPLOYEE,
|
|
73
|
+
pubOp: "pubEmployees", // useManageEmployee.js:7
|
|
74
|
+
sendFrame: { action: ACT_EMPLOYEE, companyID, op: "get" }, // :18-22
|
|
75
|
+
timeoutMs,
|
|
76
|
+
// pubEmployees の chunk 形: { totalCount, data:{ list, page } } (:71-88)
|
|
77
|
+
parseChunk: (msg) => {
|
|
78
|
+
const totalCount = msg?.data?.totalCount;
|
|
79
|
+
const inner = msg?.data?.data ?? {};
|
|
80
|
+
return { totalCount, list: inner.list ?? [], page: inner.page ?? 1 };
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* ログイン中の自分自身の社員情報を取得する。companyID も items も不要。
|
|
87
|
+
* biz3: registerCallback(action,'currentInfo',cb) で同期受信 (useManageEmployee.js:187-197)。
|
|
88
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
89
|
+
* @returns {Promise<object>} 応答 message (data 構造は biz3 では未確認: 呼出側 me/index.js 依存)
|
|
90
|
+
*/
|
|
91
|
+
export async function getCurrentUserInfo(client, { timeoutMs = DEFAULT_TIMEOUT_MS } = {}) {
|
|
92
|
+
const resp = await client.request({ action: ACT_EMPLOYEE, op: "currentInfo" }, timeoutMs);
|
|
93
|
+
assertSuccess(resp, "getCurrentUserInfo");
|
|
94
|
+
return resp?.data ?? resp;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 社員を追加する。
|
|
99
|
+
* biz3: { action, items, op:'add' }。items は配列で各要素内に companyID を入れる
|
|
100
|
+
* (useManageEmployee.js:263-274, AddEmployee.js:64-78)。トップレベル companyID 無し。
|
|
101
|
+
* 各 item 例: { employeeEmail, employeeName, phone, department, tag:[...], companyID }
|
|
102
|
+
* (空 phone/department は undefined。tag はロール/タグ id の配列)。
|
|
103
|
+
*
|
|
104
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
105
|
+
* @param {{items:object[], timeoutMs?:number}} params
|
|
106
|
+
* @returns {Promise<object>} 応答 message。success:false の場合 throw
|
|
107
|
+
* (message==='Limit Exceeded' でプラン上限 — :89-100)。
|
|
108
|
+
*/
|
|
109
|
+
export async function addEmployees(client, { items, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
110
|
+
if (!Array.isArray(items)) throw new Error("items must be an array");
|
|
111
|
+
const resp = await client.request({ action: ACT_EMPLOYEE, items, op: "add" }, timeoutMs);
|
|
112
|
+
assertSuccess(resp, "addEmployees");
|
|
113
|
+
return resp;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 社員情報を更新する。
|
|
118
|
+
* biz3: update のみ obj:{companyID,...data} でラップする (useManageEmployee.js:169-185)。
|
|
119
|
+
* data は更新フィールド (例 { Name:'nickname', Value:newValue } — me/index.js:63)。
|
|
120
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
121
|
+
* @param {{companyID:string, data:object, timeoutMs?:number}} params
|
|
122
|
+
* @returns {Promise<object>} 応答 message
|
|
123
|
+
*/
|
|
124
|
+
export async function updateEmployee(client, { companyID, data, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
125
|
+
if (!companyID) throw new Error("companyID required");
|
|
126
|
+
const resp = await client.request(
|
|
127
|
+
{ action: ACT_EMPLOYEE, obj: { companyID, ...data }, op: "update" },
|
|
128
|
+
timeoutMs,
|
|
129
|
+
);
|
|
130
|
+
assertSuccess(resp, "updateEmployee");
|
|
131
|
+
return resp;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 社員を削除する。
|
|
136
|
+
* biz3: { action, items, op:'delete' }。items は社員オブジェクト配列または
|
|
137
|
+
* [{ subUUID, companyID }] (useManageEmployee.js:199-210, EmployeeItem.js:219-225)。
|
|
138
|
+
* トップレベル companyID 無し (companyID は要素内に含めるパターンあり)。
|
|
139
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
140
|
+
* @param {{items:object[], timeoutMs?:number}} params
|
|
141
|
+
* @returns {Promise<object>} 応答 message
|
|
142
|
+
*/
|
|
143
|
+
export async function removeEmployees(client, { items, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
144
|
+
if (!Array.isArray(items)) throw new Error("items must be an array");
|
|
145
|
+
const resp = await client.request({ action: ACT_EMPLOYEE, items, op: "delete" }, timeoutMs);
|
|
146
|
+
assertSuccess(resp, "removeEmployees");
|
|
147
|
+
return resp;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* 社員の並び順を更新する。
|
|
152
|
+
* biz3: { action, items, op:'order' }。各要素 { friendUUID, rank }、rank は -index
|
|
153
|
+
* (降順負値、MobileContacts.js:94-98)。friendUUID には社員の subUUID を入れる。
|
|
154
|
+
* 注: handleEmployee に order の case が無く応答は no-op (一覧再取得もしない) のため、
|
|
155
|
+
* CLI でも ack を待つだけ (request)。
|
|
156
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
157
|
+
* @param {{items:{friendUUID:string, rank:number}[], timeoutMs?:number}} params
|
|
158
|
+
* @returns {Promise<object>} 応答 message
|
|
159
|
+
*/
|
|
160
|
+
export async function reorderEmployees(client, { items, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
161
|
+
if (!Array.isArray(items)) throw new Error("items must be an array");
|
|
162
|
+
const resp = await client.request({ action: ACT_EMPLOYEE, items, op: "order" }, timeoutMs);
|
|
163
|
+
assertSuccess(resp, "reorderEmployees");
|
|
164
|
+
return resp;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* CS (カスタマーサポート) 横断で社員/ユーザーを検索する。
|
|
169
|
+
*
|
|
170
|
+
* biz3: 送信 op は 'queryByCS' だが応答購読 op は 'pubQueryByCS' (useManageEmployee.js:391-416)。
|
|
171
|
+
* page 単位の chunk が来るので page===totalPage まで蓄積し、全 list を返す。
|
|
172
|
+
* 各 chunk: res.data = { data:{ list, page }, totalPage }。
|
|
173
|
+
*
|
|
174
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
175
|
+
* @param {{keyword:string, timeoutMs?:number}} params
|
|
176
|
+
* @returns {Promise<any[]>} 全 chunk を結合した検索結果リスト
|
|
177
|
+
*/
|
|
178
|
+
export async function queryByCS(client, { keyword, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
179
|
+
if (!keyword) throw new Error("keyword required");
|
|
180
|
+
return collectChunks(client, {
|
|
181
|
+
action: ACT_EMPLOYEE,
|
|
182
|
+
pubOp: "pubQueryByCS", // useManageEmployee.js:411,415
|
|
183
|
+
sendFrame: { action: ACT_EMPLOYEE, keyword, op: "queryByCS" }, // :394-398
|
|
184
|
+
timeoutMs,
|
|
185
|
+
returnListOnly: true,
|
|
186
|
+
// chunk 形: res.data = { data:{ list, page }, totalPage } (:405-408)
|
|
187
|
+
parseChunk: (msg) => {
|
|
188
|
+
const top = msg?.data ?? {};
|
|
189
|
+
const inner = top.data ?? {};
|
|
190
|
+
return {
|
|
191
|
+
list: inner.list ?? [],
|
|
192
|
+
page: inner.page ?? 1,
|
|
193
|
+
totalPage: top.totalPage ?? 1,
|
|
194
|
+
};
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* queryByCS で見つけたユーザーを確定する。
|
|
201
|
+
* biz3: { action, email, op:'confirmQueryByCS' } (useManageEmployee.js:420-432)。
|
|
202
|
+
* 注: 成功すると biz3 UI は現セッションを signout する設計 (CSUserSearchDialog.js:127)。
|
|
203
|
+
* CLI でこの op を投げる場合は副作用に注意。
|
|
204
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
205
|
+
* @param {{email:string, timeoutMs?:number}} params
|
|
206
|
+
* @returns {Promise<object>} 応答 message
|
|
207
|
+
*/
|
|
208
|
+
export async function confirmQueryByCS(client, { email, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
209
|
+
if (!email) throw new Error("email required");
|
|
210
|
+
const resp = await client.request(
|
|
211
|
+
{ action: ACT_EMPLOYEE, email, op: "confirmQueryByCS" },
|
|
212
|
+
timeoutMs,
|
|
213
|
+
);
|
|
214
|
+
assertSuccess(resp, "confirmQueryByCS");
|
|
215
|
+
return resp;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
219
|
+
// employeeGroup (biz3ManageEmployeeGroup)
|
|
220
|
+
// 注: companyID のキー名は 'cid' (getBindDeviceGroup を除く)。
|
|
221
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* 従業員グループ一覧を取得する。
|
|
225
|
+
* biz3: { action, cid, op:'getGroups' }、応答 data=グループ配列 (useManageEmployee.js:25-33,47-49)。
|
|
226
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
227
|
+
* @param {{companyID:string, timeoutMs?:number}} params
|
|
228
|
+
* @returns {Promise<any[]>} グループ配列
|
|
229
|
+
*/
|
|
230
|
+
export async function getEmployeeGroups(client, { companyID, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
231
|
+
if (!companyID) throw new Error("companyID required");
|
|
232
|
+
const resp = await client.request(
|
|
233
|
+
{ action: ACT_EMPLOYEE_GROUP, cid: companyID, op: "getGroups" },
|
|
234
|
+
timeoutMs,
|
|
235
|
+
);
|
|
236
|
+
assertSuccess(resp, "getEmployeeGroups");
|
|
237
|
+
return resp?.data ?? [];
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* 従業員グループを追加する。
|
|
242
|
+
* biz3: obj:{cid,...item} でラップ (useManageEmployee.js:212-228)。応答 data=追加グループ1件。
|
|
243
|
+
* item の具体フィールド (グループ名等) は biz3 UI 依存で未確認。
|
|
244
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
245
|
+
* @param {{companyID:string, item:object, timeoutMs?:number}} params
|
|
246
|
+
* @returns {Promise<object>} 追加されたグループ (resp.data)
|
|
247
|
+
*/
|
|
248
|
+
export async function addEmployeeGroup(client, { companyID, item, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
249
|
+
if (!companyID) throw new Error("companyID required");
|
|
250
|
+
const resp = await client.request(
|
|
251
|
+
{ action: ACT_EMPLOYEE_GROUP, obj: { cid: companyID, ...item }, op: "add" },
|
|
252
|
+
timeoutMs,
|
|
253
|
+
);
|
|
254
|
+
assertSuccess(resp, "addEmployeeGroup");
|
|
255
|
+
return resp?.data ?? resp;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* 従業員グループ情報を更新する。
|
|
260
|
+
* biz3: obj:{cid,...item} でラップ (useManageEmployee.js:230-246)。item に gid 等を含める想定。
|
|
261
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
262
|
+
* @param {{companyID:string, item:object, timeoutMs?:number}} params
|
|
263
|
+
* @returns {Promise<object>} 応答 message
|
|
264
|
+
*/
|
|
265
|
+
export async function updateEmployeeGroup(client, { companyID, item, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
266
|
+
if (!companyID) throw new Error("companyID required");
|
|
267
|
+
const resp = await client.request(
|
|
268
|
+
{ action: ACT_EMPLOYEE_GROUP, obj: { cid: companyID, ...item }, op: "update" },
|
|
269
|
+
timeoutMs,
|
|
270
|
+
);
|
|
271
|
+
assertSuccess(resp, "updateEmployeeGroup");
|
|
272
|
+
return resp;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* 従業員グループを削除する (複数可)。
|
|
277
|
+
* biz3: { action, objs:<gids>, cid, op:'deleteGroups' } (useManageEmployee.js:248-261)。
|
|
278
|
+
* objs はトップレベル配列。gids の各要素型は biz3 UI 依存で未確認。
|
|
279
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
280
|
+
* @param {{companyID:string, gids:any[], timeoutMs?:number}} params
|
|
281
|
+
* @returns {Promise<object>} 応答 message
|
|
282
|
+
*/
|
|
283
|
+
export async function removeEmployeeGroups(client, { companyID, gids, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
284
|
+
if (!companyID) throw new Error("companyID required");
|
|
285
|
+
if (!Array.isArray(gids)) throw new Error("gids must be an array");
|
|
286
|
+
const resp = await client.request(
|
|
287
|
+
{ action: ACT_EMPLOYEE_GROUP, objs: gids, cid: companyID, op: "deleteGroups" },
|
|
288
|
+
timeoutMs,
|
|
289
|
+
);
|
|
290
|
+
assertSuccess(resp, "removeEmployeeGroups");
|
|
291
|
+
return resp;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* 従業員グループに紐づくデバイスグループを取得する。
|
|
296
|
+
* biz3: { action, gid, op:'getBindDeviceGroup' } — cid は送らない (useManageEmployee.js:321-334)。
|
|
297
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
298
|
+
* @param {{gid:string, timeoutMs?:number}} params
|
|
299
|
+
* @returns {Promise<object>} 応答 message (data 構造は未確認)
|
|
300
|
+
*/
|
|
301
|
+
export async function getEmployeeGroupBindDeviceGroup(client, { gid, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
302
|
+
if (!gid) throw new Error("gid required");
|
|
303
|
+
const resp = await client.request(
|
|
304
|
+
{ action: ACT_EMPLOYEE_GROUP, gid, op: "getBindDeviceGroup" },
|
|
305
|
+
timeoutMs,
|
|
306
|
+
);
|
|
307
|
+
assertSuccess(resp, "getEmployeeGroupBindDeviceGroup");
|
|
308
|
+
return resp?.data ?? resp;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* 従業員グループにユーザーを紐付ける。
|
|
313
|
+
* biz3: { action, cid, gid, uuids, items, op:'addBindUser' } 全て直置き (useManageEmployee.js:336-352)。
|
|
314
|
+
* uuids と items は別引数で両方送る。要素構造は biz3 UI 依存で未確認。
|
|
315
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
316
|
+
* @param {{companyID:string, gid:string, uuids:any[], items:any[], timeoutMs?:number}} params
|
|
317
|
+
* @returns {Promise<object>} 応答 message
|
|
318
|
+
*/
|
|
319
|
+
export async function addEmployeeInGroup(client, { companyID, gid, uuids, items, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
320
|
+
if (!companyID) throw new Error("companyID required");
|
|
321
|
+
const resp = await client.request(
|
|
322
|
+
{ action: ACT_EMPLOYEE_GROUP, cid: companyID, gid, uuids, items, op: "addBindUser" },
|
|
323
|
+
timeoutMs,
|
|
324
|
+
);
|
|
325
|
+
assertSuccess(resp, "addEmployeeInGroup");
|
|
326
|
+
return resp;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* 従業員グループからユーザーを解除する。
|
|
331
|
+
* biz3: items を {subUUID} のみに絞り込んで送る (useManageEmployee.js:354-373, :358-360)。
|
|
332
|
+
* uuids は引数そのまま。cid/gid/uuids/items 全て直置き。
|
|
333
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
334
|
+
* @param {{companyID:string, gid:string, uuids:any[], items:{subUUID:string}[], timeoutMs?:number}} params
|
|
335
|
+
* @returns {Promise<object>} 応答 message
|
|
336
|
+
*/
|
|
337
|
+
export async function removeEmployeeInGroup(client, { companyID, gid, uuids, items, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
338
|
+
if (!companyID) throw new Error("companyID required");
|
|
339
|
+
if (!Array.isArray(items)) throw new Error("items must be an array");
|
|
340
|
+
// biz3 useManageEmployee.js:358-360 と同じく {subUUID} だけに絞る。
|
|
341
|
+
const params = items.map((item) => ({ subUUID: item.subUUID }));
|
|
342
|
+
const resp = await client.request(
|
|
343
|
+
{ action: ACT_EMPLOYEE_GROUP, cid: companyID, gid, uuids, items: params, op: "removeBindUser" },
|
|
344
|
+
timeoutMs,
|
|
345
|
+
);
|
|
346
|
+
assertSuccess(resp, "removeEmployeeInGroup");
|
|
347
|
+
return resp;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* 従業員グループからデバイスグループを解除する。
|
|
352
|
+
* biz3: { action, cid, ...data, op:'removeBindDeviceGroup' } (useManageEmployee.js:375-389)。
|
|
353
|
+
* data の中身 (gid 等) は biz3 UI 依存で未確認。
|
|
354
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
355
|
+
* @param {{companyID:string, data:object, timeoutMs?:number}} params
|
|
356
|
+
* @returns {Promise<object>} 応答 message
|
|
357
|
+
*/
|
|
358
|
+
export async function removeEmployeeGroupBindDeviceGroup(client, { companyID, data, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
359
|
+
if (!companyID) throw new Error("companyID required");
|
|
360
|
+
const resp = await client.request(
|
|
361
|
+
{ action: ACT_EMPLOYEE_GROUP, cid: companyID, ...data, op: "removeBindDeviceGroup" },
|
|
362
|
+
timeoutMs,
|
|
363
|
+
);
|
|
364
|
+
assertSuccess(resp, "removeEmployeeGroupBindDeviceGroup");
|
|
365
|
+
return resp;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
369
|
+
// role / tags (biz3ManageRole)
|
|
370
|
+
// 注: ここだけ companyID のキー名は 'companyID' (employeeGroup 系の 'cid' と異なる)。
|
|
371
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* 役割タグ一覧を取得する。
|
|
375
|
+
* biz3: { action, companyID, op:'get' }、応答 data=タグ配列 (useManageEmployee.js:35-43,116-127)。
|
|
376
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
377
|
+
* @param {{companyID:string, timeoutMs?:number}} params
|
|
378
|
+
* @returns {Promise<any[]>} タグ配列
|
|
379
|
+
*/
|
|
380
|
+
export async function getTags(client, { companyID, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
381
|
+
if (!companyID) throw new Error("companyID required");
|
|
382
|
+
const resp = await client.request(
|
|
383
|
+
{ action: ACT_ROLE, companyID, op: "get" },
|
|
384
|
+
timeoutMs,
|
|
385
|
+
);
|
|
386
|
+
assertSuccess(resp, "getTags");
|
|
387
|
+
return resp?.data ?? [];
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* 役割タグを追加/更新する。
|
|
392
|
+
* biz3: { action, companyID, ...data, op:'post' } (useManageEmployee.js:289-303)。
|
|
393
|
+
* op:'post' は ...data の後に置き、data 内の op を上書きする (順序が一次資料どおり重要)。
|
|
394
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
395
|
+
* @param {{companyID:string, data:object, timeoutMs?:number}} params
|
|
396
|
+
* @returns {Promise<object>} 応答 message
|
|
397
|
+
*/
|
|
398
|
+
export async function postTag(client, { companyID, data, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
399
|
+
if (!companyID) throw new Error("companyID required");
|
|
400
|
+
const resp = await client.request(
|
|
401
|
+
{ action: ACT_ROLE, companyID, ...data, op: "post" },
|
|
402
|
+
timeoutMs,
|
|
403
|
+
);
|
|
404
|
+
assertSuccess(resp, "postTag");
|
|
405
|
+
return resp;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* 役割タグを削除する。
|
|
410
|
+
* biz3: { action, companyID, ...data, op:'delete' } (useManageEmployee.js:305-319)。
|
|
411
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
412
|
+
* @param {{companyID:string, data:object, timeoutMs?:number}} params
|
|
413
|
+
* @returns {Promise<object>} 応答 message
|
|
414
|
+
*/
|
|
415
|
+
export async function removeTag(client, { companyID, data, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
416
|
+
if (!companyID) throw new Error("companyID required");
|
|
417
|
+
const resp = await client.request(
|
|
418
|
+
{ action: ACT_ROLE, companyID, ...data, op: "delete" },
|
|
419
|
+
timeoutMs,
|
|
420
|
+
);
|
|
421
|
+
assertSuccess(resp, "removeTag");
|
|
422
|
+
return resp;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
426
|
+
// deviceGroup (biz3ManageDeviceGroup)
|
|
427
|
+
// 注: companyID のキー名は 'cid' (getBindUserGroup は cid 無し)。
|
|
428
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* デバイスグループ一覧を取得する。
|
|
432
|
+
* biz3: { action, cid, op:'getGroups' }、応答 data=配列 (useManageGroup.js:11-19,27-33)。
|
|
433
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
434
|
+
* @param {{companyID:string, timeoutMs?:number}} params
|
|
435
|
+
* @returns {Promise<any[]>} デバイスグループ配列
|
|
436
|
+
*/
|
|
437
|
+
export async function getDeviceGroups(client, { companyID, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
438
|
+
if (!companyID) throw new Error("companyID required");
|
|
439
|
+
const resp = await client.request(
|
|
440
|
+
{ action: ACT_DEVICE_GROUP, cid: companyID, op: "getGroups" },
|
|
441
|
+
timeoutMs,
|
|
442
|
+
);
|
|
443
|
+
assertSuccess(resp, "getDeviceGroups");
|
|
444
|
+
return resp?.data ?? [];
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* デバイスグループを作成する。
|
|
449
|
+
* biz3: obj:{name,cid,uuids} でラップ (useManageGroup.js:84-102)。
|
|
450
|
+
* uuids は作成時に含めるデバイス UUID 配列。
|
|
451
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
452
|
+
* @param {{companyID:string, name:string, uuids:string[], timeoutMs?:number}} params
|
|
453
|
+
* @returns {Promise<object>} 応答 message
|
|
454
|
+
*/
|
|
455
|
+
export async function addDeviceGroup(client, { companyID, name, uuids = [], timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
456
|
+
if (!companyID) throw new Error("companyID required");
|
|
457
|
+
const resp = await client.request(
|
|
458
|
+
{ action: ACT_DEVICE_GROUP, obj: { name, cid: companyID, uuids }, op: "add" },
|
|
459
|
+
timeoutMs,
|
|
460
|
+
);
|
|
461
|
+
assertSuccess(resp, "addDeviceGroup");
|
|
462
|
+
return resp;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* デバイスグループ情報を更新する。
|
|
467
|
+
* biz3: obj:{cid,...item} でラップ (useManageGroup.js:310-326)。item に gid 等を含める想定。
|
|
468
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
469
|
+
* @param {{companyID:string, item:object, timeoutMs?:number}} params
|
|
470
|
+
* @returns {Promise<object>} 応答 message
|
|
471
|
+
*/
|
|
472
|
+
export async function updateDeviceGroup(client, { companyID, item, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
473
|
+
if (!companyID) throw new Error("companyID required");
|
|
474
|
+
const resp = await client.request(
|
|
475
|
+
{ action: ACT_DEVICE_GROUP, obj: { cid: companyID, ...item }, op: "update" },
|
|
476
|
+
timeoutMs,
|
|
477
|
+
);
|
|
478
|
+
assertSuccess(resp, "updateDeviceGroup");
|
|
479
|
+
return resp;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* デバイスグループを削除する (複数可)。
|
|
484
|
+
* biz3: groupIds の各 obj に cid をマージした配列を objs(複数形) に入れる
|
|
485
|
+
* (useManageGroup.js:67-82)。obj(単数) ではなく objs。
|
|
486
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
487
|
+
* @param {{companyID:string, groupIds:object[], timeoutMs?:number}} params
|
|
488
|
+
* @returns {Promise<object>} 応答 message
|
|
489
|
+
*/
|
|
490
|
+
export async function removeDeviceGroups(client, { companyID, groupIds, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
491
|
+
if (!companyID) throw new Error("companyID required");
|
|
492
|
+
if (!Array.isArray(groupIds)) throw new Error("groupIds must be an array");
|
|
493
|
+
// biz3 useManageGroup.js:71-74 と同じく各要素に cid をマージ。
|
|
494
|
+
const objs = groupIds.map((obj) => ({ ...obj, cid: companyID }));
|
|
495
|
+
const resp = await client.request(
|
|
496
|
+
{ action: ACT_DEVICE_GROUP, objs, op: "deleteGroups" },
|
|
497
|
+
timeoutMs,
|
|
498
|
+
);
|
|
499
|
+
assertSuccess(resp, "removeDeviceGroups");
|
|
500
|
+
return resp;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* デバイスグループにデバイスを紐付ける。
|
|
505
|
+
* biz3: { action, cid, gid, uuids, items, op:'addBindDevice' } 全て直置き (useManageGroup.js:240-256)。
|
|
506
|
+
* removeBindDevice と異なり items は絞り込まず透過する。
|
|
507
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
508
|
+
* @param {{companyID:string, gid:string, uuids:any[], items:any[], timeoutMs?:number}} params
|
|
509
|
+
* @returns {Promise<object>} 応答 message
|
|
510
|
+
*/
|
|
511
|
+
export async function addDeviceInGroup(client, { companyID, gid, uuids, items, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
512
|
+
if (!companyID) throw new Error("companyID required");
|
|
513
|
+
const resp = await client.request(
|
|
514
|
+
{ action: ACT_DEVICE_GROUP, cid: companyID, gid, uuids, items, op: "addBindDevice" },
|
|
515
|
+
timeoutMs,
|
|
516
|
+
);
|
|
517
|
+
assertSuccess(resp, "addDeviceInGroup");
|
|
518
|
+
return resp;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* デバイスグループからデバイスを解除する。
|
|
523
|
+
* biz3: items を必ず {deviceUUID, secretKey} のみに絞り込んで送る (useManageGroup.js:218-238, :222-225)。
|
|
524
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
525
|
+
* @param {{companyID:string, gid:string, uuids:any[], items:{deviceUUID:string,secretKey:string}[], timeoutMs?:number}} params
|
|
526
|
+
* @returns {Promise<object>} 応答 message
|
|
527
|
+
*/
|
|
528
|
+
export async function removeDeviceInGroup(client, { companyID, gid, uuids, items, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
529
|
+
if (!companyID) throw new Error("companyID required");
|
|
530
|
+
if (!Array.isArray(items)) throw new Error("items must be an array");
|
|
531
|
+
// biz3 useManageGroup.js:222-225 と同じく {deviceUUID, secretKey} だけに絞る。
|
|
532
|
+
const params = items.map((item) => ({ deviceUUID: item.deviceUUID, secretKey: item.secretKey }));
|
|
533
|
+
const resp = await client.request(
|
|
534
|
+
{ action: ACT_DEVICE_GROUP, cid: companyID, gid, uuids, items: params, op: "removeBindDevice" },
|
|
535
|
+
timeoutMs,
|
|
536
|
+
);
|
|
537
|
+
assertSuccess(resp, "removeDeviceInGroup");
|
|
538
|
+
return resp;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* デバイスグループにバインド済みの従業員グループを取得する。
|
|
543
|
+
* biz3: { action, gid, op:'getBindUserGroup' } — cid 無し (useManageGroup.js:189-200)。
|
|
544
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
545
|
+
* @param {{gid:string, timeoutMs?:number}} params
|
|
546
|
+
* @returns {Promise<object>} 応答 message (data 構造は未確認)
|
|
547
|
+
*/
|
|
548
|
+
export async function getDeviceGroupBindUserGroup(client, { gid, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
549
|
+
if (!gid) throw new Error("gid required");
|
|
550
|
+
const resp = await client.request(
|
|
551
|
+
{ action: ACT_DEVICE_GROUP, gid, op: "getBindUserGroup" },
|
|
552
|
+
timeoutMs,
|
|
553
|
+
);
|
|
554
|
+
assertSuccess(resp, "getDeviceGroupBindUserGroup");
|
|
555
|
+
return resp?.data ?? resp;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* デバイスグループから従業員グループを解除する。
|
|
560
|
+
* biz3: { action, cid, ...data, op:'removeBindUserGroup' } (useManageGroup.js:202-216)。
|
|
561
|
+
* data の中身 (gid/uuids 等) は biz3 UI 依存で未確認。
|
|
562
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
563
|
+
* @param {{companyID:string, data:object, timeoutMs?:number}} params
|
|
564
|
+
* @returns {Promise<object>} 応答 message
|
|
565
|
+
*/
|
|
566
|
+
export async function removeDeviceGroupBindUserGroup(client, { companyID, data, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
567
|
+
if (!companyID) throw new Error("companyID required");
|
|
568
|
+
const resp = await client.request(
|
|
569
|
+
{ action: ACT_DEVICE_GROUP, cid: companyID, ...data, op: "removeBindUserGroup" },
|
|
570
|
+
timeoutMs,
|
|
571
|
+
);
|
|
572
|
+
assertSuccess(resp, "removeDeviceGroupBindUserGroup");
|
|
573
|
+
return resp;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
577
|
+
// employeeDevice (biz3ManageEmployeeDevice) — デバイス鍵の共有/取消/列挙
|
|
578
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* 従業員にデバイス鍵を共有する。
|
|
582
|
+
* biz3: { action, items, op:'add' }、companyID 無し (useManageGroup.js:106-119)。
|
|
583
|
+
* items は呼出側 (DeviceShare.js:65-76) で {...device, ...user, keyLevel, startTime, endTime}
|
|
584
|
+
* を生成。keyLevel: 0=owner,1=manager,2=guest。startTime/endTime は keyLevel==2 一時利用時のみ
|
|
585
|
+
* epoch 秒、それ以外は空文字 ''。
|
|
586
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
587
|
+
* @param {{items:object[], timeoutMs?:number}} params
|
|
588
|
+
* @returns {Promise<object>} 応答 message
|
|
589
|
+
*/
|
|
590
|
+
export async function shareDeviceKeysToEmployees(client, { items, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
591
|
+
if (!Array.isArray(items)) throw new Error("items must be an array");
|
|
592
|
+
const resp = await client.request(
|
|
593
|
+
{ action: ACT_EMPLOYEE_DEVICE, items, op: "add" },
|
|
594
|
+
timeoutMs,
|
|
595
|
+
);
|
|
596
|
+
assertSuccess(resp, "shareDeviceKeysToEmployees");
|
|
597
|
+
return resp;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* 従業員グループにデバイスグループ鍵を共有する。
|
|
602
|
+
* biz3: { action, ...item, companyID, op:'group' } (useManageGroup.js:121-135)。
|
|
603
|
+
* companyID キーは 'companyID' (cid ではない)。item (GroupShare.js:75-89) =
|
|
604
|
+
* { keyLevel(文字列 '0'/'1'/'2'), members:[subUUID...], devices:[deviceUUID...](ユニーク),
|
|
605
|
+
* mid:メンバーグループgid, dids:[デバイスグループgid...], startTime, endTime }。
|
|
606
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
607
|
+
* @param {{companyID:string, item:object, timeoutMs?:number}} params
|
|
608
|
+
* @returns {Promise<object>} 応答 message
|
|
609
|
+
*/
|
|
610
|
+
export async function shareDeviceGroupKeysToEmployeeGroup(client, { companyID, item, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
611
|
+
if (!companyID) throw new Error("companyID required");
|
|
612
|
+
const resp = await client.request(
|
|
613
|
+
{ action: ACT_EMPLOYEE_DEVICE, ...item, companyID, op: "group" },
|
|
614
|
+
timeoutMs,
|
|
615
|
+
);
|
|
616
|
+
assertSuccess(resp, "shareDeviceGroupKeysToEmployeeGroup");
|
|
617
|
+
return resp;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* 指定 subUUID の従業員が持つデバイス鍵一覧を取得する。
|
|
622
|
+
* biz3: { action, subUUID, op:'get' }、companyID 無し (useManageGroup.js:137-148)。
|
|
623
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
624
|
+
* @param {{subUUID:string, timeoutMs?:number}} params
|
|
625
|
+
* @returns {Promise<object>} 応答 message (data 構造は未確認)
|
|
626
|
+
*/
|
|
627
|
+
export async function getEmployeeDeviceKeys(client, { subUUID, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
628
|
+
if (!subUUID) throw new Error("subUUID required");
|
|
629
|
+
const resp = await client.request(
|
|
630
|
+
{ action: ACT_EMPLOYEE_DEVICE, subUUID, op: "get" },
|
|
631
|
+
timeoutMs,
|
|
632
|
+
);
|
|
633
|
+
assertSuccess(resp, "getEmployeeDeviceKeys");
|
|
634
|
+
return resp?.data ?? resp;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* 従業員/ゲストのデバイス鍵を削除する。
|
|
639
|
+
* biz3: { action, ...data, op:'del' }、companyID 無し (useManageGroup.js:150-161)。
|
|
640
|
+
* data は 2 パターン (DeviceUserList.js:117-132):
|
|
641
|
+
* (A) ゲスト鍵削除 = { guestKeyId, randomTag, deviceUUID }
|
|
642
|
+
* randomTag = await crypto.cmacTime(device.secretKey) を呼出側で生成して渡す。
|
|
643
|
+
* (B) 通常従業員削除 = { subUUID, deviceUUID } (randomTag 不要)。
|
|
644
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
645
|
+
* @param {{data:object, timeoutMs?:number}} params
|
|
646
|
+
* @returns {Promise<object>} 応答 message
|
|
647
|
+
*/
|
|
648
|
+
export async function removeEmployeeDeviceKey(client, { data, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
649
|
+
if (!data || typeof data !== "object") throw new Error("data required");
|
|
650
|
+
const resp = await client.request(
|
|
651
|
+
{ action: ACT_EMPLOYEE_DEVICE, ...data, op: "del" },
|
|
652
|
+
timeoutMs,
|
|
653
|
+
);
|
|
654
|
+
assertSuccess(resp, "removeEmployeeDeviceKey");
|
|
655
|
+
return resp;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* ゲスト鍵の名称タグを更新する。
|
|
660
|
+
* biz3: { action, ...data, op:'updateGuestTag' } (useManageGroup.js:163-174)。
|
|
661
|
+
* data = { deviceUUID, guestKeyId, keyName } (DeviceUserList.js:146-151)。keyName が新タグ名。
|
|
662
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
663
|
+
* @param {{data:{deviceUUID:string,guestKeyId:string,keyName:string}, timeoutMs?:number}} params
|
|
664
|
+
* @returns {Promise<object>} 応答 message
|
|
665
|
+
*/
|
|
666
|
+
export async function updateGuestKeyTag(client, { data, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
667
|
+
if (!data || typeof data !== "object") throw new Error("data required");
|
|
668
|
+
const resp = await client.request(
|
|
669
|
+
{ action: ACT_EMPLOYEE_DEVICE, ...data, op: "updateGuestTag" },
|
|
670
|
+
timeoutMs,
|
|
671
|
+
);
|
|
672
|
+
assertSuccess(resp, "updateGuestKeyTag");
|
|
673
|
+
return resp;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* ゲスト用 guestKeyId を発行する (招待 QR の元になる)。
|
|
678
|
+
* biz3: { action, ...data, op:'generateGuestQR' } (useManageGroup.js:176-187)。
|
|
679
|
+
* data = currentDeviceKey (デバイス鍵オブジェクト全体: deviceUUID, secretKey,
|
|
680
|
+
* sesame2PublicKey, keyIndex, deviceModel, deviceName, keyLevel 等) を spread
|
|
681
|
+
* (MobileDeviceShareQRCode.js:58)。
|
|
682
|
+
* 応答: res.success 必須、res.data = guestKeyId (文字列。QR の sk 生成に使う)。
|
|
683
|
+
* 注: QR URL/画像化は別段 (biz3utils generateInviteGuestQRCodeByInfo) で本 op の対象外。
|
|
684
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
685
|
+
* @param {{data:object, timeoutMs?:number}} params
|
|
686
|
+
* @returns {Promise<string>} guestKeyId
|
|
687
|
+
*/
|
|
688
|
+
export async function generateGuestQR(client, { data, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
689
|
+
if (!data || typeof data !== "object") throw new Error("data required");
|
|
690
|
+
const resp = await client.request(
|
|
691
|
+
{ action: ACT_EMPLOYEE_DEVICE, ...data, op: "generateGuestQR" },
|
|
692
|
+
timeoutMs,
|
|
693
|
+
);
|
|
694
|
+
assertSuccess(resp, "generateGuestQR");
|
|
695
|
+
return resp.data; // guestKeyId (MobileDeviceShareQRCode.js:58-69)
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
699
|
+
// getDeviceEmployeeKeys (biz3GetDeviceEmployeeKeys) — デバイス側から鍵保有従業員を列挙
|
|
700
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* デバイス側から、その鍵を保有する従業員を列挙する。
|
|
704
|
+
* biz3: { action, deviceUUID, companyID, limit, op:'get' } (useManageGroup.js:258-275)。
|
|
705
|
+
* companyID 必須。limit=0 で全件 / 5 で非管理モード (DeviceUserList)。
|
|
706
|
+
* 応答: resp.data = 配列。各 item = { keyLevel(数値:2=guest), subUUID, employeeName,
|
|
707
|
+
* guestKeyId(ゲスト時に length>0), ... } (DeviceUserList.js:29-40,119)。
|
|
708
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
709
|
+
* @param {{deviceUUID:string, companyID:string, limit?:number, timeoutMs?:number}} params
|
|
710
|
+
* @returns {Promise<any[]>} 鍵保有従業員の配列
|
|
711
|
+
*/
|
|
712
|
+
export async function getDeviceEmployeeKeys(client, { deviceUUID, companyID, limit = 0, timeoutMs = DEFAULT_TIMEOUT_MS }) {
|
|
713
|
+
if (!deviceUUID) throw new Error("deviceUUID required");
|
|
714
|
+
if (!companyID) throw new Error("companyID required");
|
|
715
|
+
const resp = await client.request(
|
|
716
|
+
{ action: ACT_DEVICE_EMP_KEYS, deviceUUID, companyID, limit, op: "get" },
|
|
717
|
+
timeoutMs,
|
|
718
|
+
);
|
|
719
|
+
assertSuccess(resp, "getDeviceEmployeeKeys");
|
|
720
|
+
return resp?.data ?? [];
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
724
|
+
// internal helper: chunk 集約 (pubEmployees / pubQueryByCS)
|
|
725
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* 別 op の async push (pubEmployees / pubQueryByCS) を購読し、page 単位の chunk を
|
|
729
|
+
* 蓄積して 1 配列にまとめて返す。biz3 は request の op と push の op が異なるため
|
|
730
|
+
* (例 send:'get' → push:'pubEmployees')、request では待てず subscribe で受ける必要がある。
|
|
731
|
+
*
|
|
732
|
+
* 完了判定:
|
|
733
|
+
* - parseChunk が totalPage を返す場合 (queryByCS): page===totalPage で完了。
|
|
734
|
+
* - parseChunk が totalCount を返す場合 (pubEmployees): 蓄積件数 >= totalCount で完了
|
|
735
|
+
* (totalCount===0 や 1 ページのみでも即完了)。
|
|
736
|
+
*
|
|
737
|
+
* @param {import("./transport.js").Hub3WsClient} client
|
|
738
|
+
* @param {{
|
|
739
|
+
* action:string,
|
|
740
|
+
* pubOp:string,
|
|
741
|
+
* sendFrame:object,
|
|
742
|
+
* timeoutMs:number,
|
|
743
|
+
* parseChunk:(msg:any)=>{list:any[], page:number, totalPage?:number, totalCount?:number},
|
|
744
|
+
* returnListOnly?:boolean,
|
|
745
|
+
* }} cfg
|
|
746
|
+
* @returns {Promise<{count:number, list:any[]} | any[]>}
|
|
747
|
+
*/
|
|
748
|
+
function collectChunks(client, cfg) {
|
|
749
|
+
const { action, pubOp, sendFrame, timeoutMs, parseChunk, returnListOnly } = cfg;
|
|
750
|
+
return new Promise((resolve, reject) => {
|
|
751
|
+
let done = false;
|
|
752
|
+
let acc = [];
|
|
753
|
+
let total = null; // totalCount (件数) を見るモード用
|
|
754
|
+
const finish = (err) => {
|
|
755
|
+
if (done) return;
|
|
756
|
+
done = true;
|
|
757
|
+
clearTimeout(to);
|
|
758
|
+
unsub();
|
|
759
|
+
if (err) reject(err);
|
|
760
|
+
else resolve(returnListOnly ? acc : { count: total ?? acc.length, list: acc });
|
|
761
|
+
};
|
|
762
|
+
const to = setTimeout(() => finish(new Error(`${action}:${pubOp} timeout`)), timeoutMs);
|
|
763
|
+
const unsub = client.subscribe(`${action}:${pubOp}`, (msg) => {
|
|
764
|
+
if (done) return;
|
|
765
|
+
if (msg?.success === false) {
|
|
766
|
+
finish(new Error(`${action}:${pubOp} failed: ${msg.message || JSON.stringify(msg)}`));
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
let chunk;
|
|
770
|
+
try { chunk = parseChunk(msg); }
|
|
771
|
+
catch (e) { finish(e); return; }
|
|
772
|
+
|
|
773
|
+
// page===1 で全置換、それ以外は追記 (biz3 pubEmployees の蓄積規則と同じ :75-87)。
|
|
774
|
+
if (chunk.page === 1) acc = [...chunk.list];
|
|
775
|
+
else acc = [...acc, ...chunk.list];
|
|
776
|
+
|
|
777
|
+
if (typeof chunk.totalCount === "number") total = chunk.totalCount;
|
|
778
|
+
|
|
779
|
+
// 完了判定。
|
|
780
|
+
if (typeof chunk.totalPage === "number") {
|
|
781
|
+
if (chunk.page >= chunk.totalPage) finish(null);
|
|
782
|
+
} else if (typeof chunk.totalCount === "number") {
|
|
783
|
+
if (acc.length >= chunk.totalCount) finish(null);
|
|
784
|
+
}
|
|
785
|
+
// どちらも無い場合は timeout まで待つ (chunk 形不明時の保険)。
|
|
786
|
+
});
|
|
787
|
+
client.send(sendFrame);
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// 公開 op の allowlist (SesameHub3._bindNs / serve registry が参照する単一の真実)。
|
|
792
|
+
export const NAMESPACE_OPS = [
|
|
793
|
+
"getEmployees", "getCurrentUserInfo", "addEmployees", "updateEmployee",
|
|
794
|
+
"removeEmployees", "reorderEmployees", "queryByCS", "confirmQueryByCS",
|
|
795
|
+
"getEmployeeGroups", "addEmployeeGroup", "updateEmployeeGroup", "removeEmployeeGroups",
|
|
796
|
+
"getEmployeeGroupBindDeviceGroup", "addEmployeeInGroup", "removeEmployeeInGroup",
|
|
797
|
+
"removeEmployeeGroupBindDeviceGroup", "getTags", "postTag", "removeTag",
|
|
798
|
+
"getDeviceGroups", "addDeviceGroup", "updateDeviceGroup", "removeDeviceGroups",
|
|
799
|
+
"addDeviceInGroup", "removeDeviceInGroup", "getDeviceGroupBindUserGroup",
|
|
800
|
+
"removeDeviceGroupBindUserGroup", "shareDeviceKeysToEmployees",
|
|
801
|
+
"shareDeviceGroupKeysToEmployeeGroup", "getEmployeeDeviceKeys", "removeEmployeeDeviceKey",
|
|
802
|
+
"updateGuestKeyTag", "generateGuestQR", "getDeviceEmployeeKeys",
|
|
803
|
+
];
|