Add manual IM bot credential access

This commit is contained in:
xmanrui 2026-08-16 01:54:06 +08:00
parent d5d2c18ce0
commit 7123fce47a
42 changed files with 2458 additions and 889 deletions

View file

@ -47,4 +47,5 @@ test('isAllowedSender enforces an open-id allowlist', () => {
assert.equal(isAllowedSender(event, new Set()), false);
assert.equal(isAllowedSender(event, new Set(['ou_allowed'])), true);
assert.equal(isAllowedSender(event, new Set(['ou_other'])), false);
assert.equal(isAllowedSender(event, new Set(['*'])), true);
});

View file

@ -143,6 +143,23 @@ async function completeScan(fx, result) {
return fx.controller.registrationStatus(attemptId);
}
test('manual Feishu credentials are verified, stored host-side, and use app visibility for access', async () => {
const fx = fixture({ createBotIds: ['bot_manual'] });
const status = await fx.controller.bindCredentials({
appId: 'cli_manual',
appSecret: 'manual-private-secret',
});
assert.equal(status.totals.connected, 1);
assert.equal(fx.configStore.bots.length, 1);
assert.deepEqual(fx.configStore.bots[0].ownerOpenIds, ['*']);
assert.equal(fx.values.get(fx.configStore.bots[0].secretRef), 'manual-private-secret');
assert.equal(fx.runtimes.get('bot_manual')[0].appSecret, 'manual-private-secret');
assert.doesNotMatch(JSON.stringify(status), /manual-private-secret|ownerOpenIds|secretRef/);
await fx.controller.close();
});
test('initialization isolates failures and starts every bot with available credentials', async () => {
const missing = bot('bot_missing', 'missing');
const healthy = bot('bot_healthy', 'healthy');

View file

@ -131,6 +131,10 @@ test('RPC dispatch matches every endpoint in client/api.js', async () => {
return current;
},
reconnect: async () => { calls.push('test'); return current; },
bindCredentials: async ({ appId, appSecret }) => {
calls.push(`bind:${appId}:${appSecret}`);
return current;
},
disconnect: async () => { calls.push('disconnect'); return status(); },
};
const fx = await rpcFixture(controller);
@ -155,6 +159,14 @@ test('RPC dispatch matches every endpoint in client/api.js', async () => {
const tested = await fx.registration.handler(FEISHU_ENDPOINTS.testConnection, {}, signal());
assert.equal(tested.ok, true);
const bound = await fx.registration.handler(
FEISHU_ENDPOINTS.bindCredentials,
{ appId: 'cli_manual', appSecret: 'manual-private-secret' },
signal(),
);
assert.equal(bound.ok, true);
assert.doesNotMatch(JSON.stringify(bound), /manual-private-secret|appSecret/);
const cancelled = await fx.registration.handler(
FEISHU_ENDPOINTS.cancelProvisioning,
{ attemptId: '7' },
@ -169,7 +181,9 @@ test('RPC dispatch matches every endpoint in client/api.js', async () => {
signal(),
);
assert.equal(disconnected.ok, true);
assert.deepEqual(calls, ['begin', 'test', 'cancel', 'disconnect']);
assert.deepEqual(calls, [
'begin', 'test', 'bind:cli_manual:manual-private-secret', 'cancel', 'disconnect',
]);
const attemptedSecret = await fx.registration.handler(
FEISHU_ENDPOINTS.beginProvisioning,