@zhin.js/host-http 1.2.0 → 1.2.2
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/lib/access-control.d.ts +19 -2
- package/lib/access-control.js +71 -3
- package/lib/console-plugin-rpc.d.ts +8 -1
- package/lib/console-plugin-rpc.js +12 -27
- package/lib/console-rpc-extended/contracts.d.ts +70 -15
- package/lib/console-rpc-extended/dispatcher.js +9 -2
- package/lib/console-rpc-extended/index.d.ts +2 -1
- package/lib/console-rpc-extended/index.js +1 -0
- package/lib/console-rpc-extended/login-rpc.d.ts +25 -2
- package/lib/console-rpc-extended/login-rpc.js +276 -16
- package/lib/console-rpc-handlers.d.ts +2 -0
- package/lib/console-rpc-handlers.js +124 -2
- package/lib/console-rpc.d.ts +0 -4
- package/lib/console-rpc.js +30 -5
- package/lib/index.d.ts +3 -3
- package/lib/index.js +2 -2
- package/package.json +3 -3
- package/src/access-control.ts +77 -3
- package/src/console-plugin-rpc.ts +13 -27
- package/src/console-rpc-extended/contracts.ts +65 -16
- package/src/console-rpc-extended/dispatcher.ts +9 -2
- package/src/console-rpc-extended/index.ts +3 -0
- package/src/console-rpc-extended/login-rpc.ts +250 -17
- package/src/console-rpc-handlers.ts +99 -2
- package/src/console-rpc.ts +33 -9
- package/src/index.ts +6 -1
package/lib/access-control.d.ts
CHANGED
|
@@ -122,6 +122,23 @@ export type ConsoleHttpDecision = Readonly<{
|
|
|
122
122
|
export declare function authorizeConsoleHttp(principal: ConsolePrincipal | undefined, method: string, relativePath: string): ConsoleHttpDecision;
|
|
123
123
|
/** WebSocket upgrade authorization for non-bootstrap principals. */
|
|
124
124
|
export declare function authorizeConsoleWebSocket(principal: ConsolePrincipal, pathname: string): boolean;
|
|
125
|
-
/**
|
|
126
|
-
|
|
125
|
+
/**
|
|
126
|
+
* JSON length of the detail of one audit entry. The gateway stores at most 4096 characters of
|
|
127
|
+
* JSON detail; statements are cut so the whole detail stays below this budget once serialised
|
|
128
|
+
* (escapes such as `\n` count twice), so the stored detail always parses.
|
|
129
|
+
*/
|
|
130
|
+
export declare const AUDIT_DETAIL_JSON_LIMIT = 3500;
|
|
131
|
+
export interface RpcAuditOptions {
|
|
132
|
+
/**
|
|
133
|
+
* Replaces literal values in SQL text (`'…'`) before it is recorded, with the dialect's own
|
|
134
|
+
* lexing (the database Host's `redactSql`). Without it no statement text is recorded at all.
|
|
135
|
+
*/
|
|
136
|
+
readonly redactSql?: (sql: string) => string;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Audit detail for an RPC: type, target and parameter key names only — plus the statement text
|
|
140
|
+
* of Console database writes (pass the reply so the DDL a schema change ran is recorded), with
|
|
141
|
+
* literals redacted by `options.redactSql`.
|
|
142
|
+
*/
|
|
143
|
+
export declare function rpcAuditDetail(message: Readonly<Record<string, unknown>>, reply?: Readonly<Record<string, unknown>>, options?: RpcAuditOptions): Readonly<Record<string, unknown>>;
|
|
127
144
|
export declare function rpcAuditTarget(rule: ConsoleRpcPermissionRule | null): string | undefined;
|
package/lib/access-control.js
CHANGED
|
@@ -128,13 +128,81 @@ export function authorizeConsoleWebSocket(principal, pathname) {
|
|
|
128
128
|
return principal.open;
|
|
129
129
|
return permission !== null && grantsAllow(principal.grants, permission);
|
|
130
130
|
}
|
|
131
|
-
/**
|
|
132
|
-
|
|
131
|
+
/**
|
|
132
|
+
* JSON length of the detail of one audit entry. The gateway stores at most 4096 characters of
|
|
133
|
+
* JSON detail; statements are cut so the whole detail stays below this budget once serialised
|
|
134
|
+
* (escapes such as `\n` count twice), so the stored detail always parses.
|
|
135
|
+
*/
|
|
136
|
+
export const AUDIT_DETAIL_JSON_LIMIT = 3_500;
|
|
137
|
+
function statementTexts(message, reply) {
|
|
138
|
+
if (message.type === 'db:execute' || message.type === 'db:query')
|
|
139
|
+
return typeof message.sql === 'string' && message.sql ? [message.sql] : [];
|
|
140
|
+
const data = reply?.data && typeof reply.data === 'object' ? reply.data : undefined;
|
|
141
|
+
return (Array.isArray(data?.statements) ? data.statements : []).filter((entry) => typeof entry === 'string' && !!entry);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Statement text of Console SQL (`db:query` / `db:execute`, the DDL `db:schema:apply` ran or
|
|
145
|
+
* would have run), literals redacted; result rows are never recorded.
|
|
146
|
+
*/
|
|
147
|
+
function databaseStatementDetail(message, reply, options) {
|
|
148
|
+
if (message.type !== 'db:execute' && message.type !== 'db:query' && message.type !== 'db:schema:apply')
|
|
149
|
+
return {};
|
|
150
|
+
const change = message.type === 'db:schema:apply' && message.change && typeof message.change === 'object' ? message.change : {};
|
|
151
|
+
const texts = statementTexts(message, reply);
|
|
152
|
+
const redact = options?.redactSql;
|
|
153
|
+
return {
|
|
154
|
+
...(message.type === 'db:execute' && message.dryRun === true ? { dryRun: true } : {}),
|
|
155
|
+
...(typeof change.kind === 'string' ? { change: change.kind.slice(0, 64) } : {}),
|
|
156
|
+
...(typeof change.table === 'string' ? { table: change.table.slice(0, 256) } : {}),
|
|
157
|
+
...(texts.length && redact
|
|
158
|
+
? { statements: texts.map(text => { try {
|
|
159
|
+
return redact(text);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return '[unavailable]';
|
|
163
|
+
} }) }
|
|
164
|
+
: texts.length ? { statementLength: texts.reduce((total, text) => total + text.length, 0) } : {}),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/** Cuts the longest statement until the serialised detail fits {@link AUDIT_DETAIL_JSON_LIMIT}. */
|
|
168
|
+
function fitAuditDetail(detail) {
|
|
169
|
+
const statements = Array.isArray(detail.statements) ? [...detail.statements] : undefined;
|
|
170
|
+
if (!statements)
|
|
171
|
+
return detail;
|
|
172
|
+
let truncated = false;
|
|
173
|
+
for (;;) {
|
|
174
|
+
const candidate = { ...detail, statements, ...(truncated ? { truncated: true } : {}) };
|
|
175
|
+
const overflow = JSON.stringify(candidate).length - AUDIT_DETAIL_JSON_LIMIT;
|
|
176
|
+
if (overflow <= 0)
|
|
177
|
+
return { ...candidate, statements: Object.freeze(statements) };
|
|
178
|
+
truncated = true;
|
|
179
|
+
let longest = 0;
|
|
180
|
+
for (let index = 1; index < statements.length; index += 1)
|
|
181
|
+
if (statements[index].length > statements[longest].length)
|
|
182
|
+
longest = index;
|
|
183
|
+
const text = statements[longest];
|
|
184
|
+
if (text.length <= 1) {
|
|
185
|
+
statements.splice(longest, 1);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
statements[longest] = `${text.slice(0, Math.max(0, text.length - overflow - 1))}…`;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Audit detail for an RPC: type, target and parameter key names only — plus the statement text
|
|
193
|
+
* of Console database writes (pass the reply so the DDL a schema change ran is recorded), with
|
|
194
|
+
* literals redacted by `options.redactSql`.
|
|
195
|
+
*/
|
|
196
|
+
export function rpcAuditDetail(message, reply, options) {
|
|
133
197
|
const data = message.data && typeof message.data === 'object' && !Array.isArray(message.data)
|
|
134
198
|
? Object.keys(message.data).sort()
|
|
135
199
|
: [];
|
|
136
200
|
const keys = Object.keys(message).filter(key => key !== 'type' && key !== 'requestId' && key !== 'data').sort();
|
|
137
|
-
return Object.freeze({
|
|
201
|
+
return Object.freeze(fitAuditDetail({
|
|
202
|
+
type: String(message.type ?? '').slice(0, 256),
|
|
203
|
+
keys: Object.freeze([...new Set([...keys, ...data])].slice(0, 64).map(key => key.slice(0, 128))),
|
|
204
|
+
...databaseStatementDetail(message, reply, options),
|
|
205
|
+
}));
|
|
138
206
|
}
|
|
139
207
|
export function rpcAuditTarget(rule) {
|
|
140
208
|
if (!rule)
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { RuntimeConsoleRpcContext, RuntimeConsoleRpcMessage, RuntimeConsoleRpcReply } from './console-rpc.js';
|
|
2
|
+
/**
|
|
3
|
+
* Refusal of the global plugin switch (`plugin:set-enabled`, `feature.set-enabled` at `global`)
|
|
4
|
+
* by an instance: the switch is a gateway transaction (stop → write `disable_plugins` → start,
|
|
5
|
+
* rollback on failure) and is never written by the instance itself (ADR 0054 §4).
|
|
6
|
+
*/
|
|
7
|
+
export declare const PLUGIN_SWITCH_REQUIRES_GATEWAY = "\u63D2\u4EF6\u5168\u5C40\u542F\u505C\u7531\u7BA1\u7406\u7F51\u5173\u6267\u884C\uFF08\u505C\u6B62\u5B9E\u4F8B \u2192 \u5199\u5165 disable_plugins \u2192 \u542F\u52A8\uFF0C\u5931\u8D25\u56DE\u6EDA\uFF09\uFF1A\u8BF7\u5728 zhin start \u542F\u52A8\u7684 Console \u4E2D\u64CD\u4F5C\uFF0C\u6216\u8FD0\u884C zhin enable / zhin disable <\u63D2\u4EF6>";
|
|
2
8
|
/**
|
|
3
9
|
* Dispatches the plugin-management slice; undefined means the type belongs elsewhere. Package
|
|
4
10
|
* installs / updates / uninstalls are not handled in the instance: they are gateway dependency
|
|
5
|
-
* transactions (`gateway.packages.*`, ADR 0054 §4) that stop the instance first
|
|
11
|
+
* transactions (`gateway.packages.*`, ADR 0054 §4) that stop the instance first, and so is the
|
|
12
|
+
* global plugin switch (`plugin:set-enabled`, refused here).
|
|
6
13
|
*/
|
|
7
14
|
export declare function dispatchPluginConsoleRpc(type: string, message: RuntimeConsoleRpcMessage, ctx: RuntimeConsoleRpcContext): Promise<RuntimeConsoleRpcReply | undefined>;
|
|
@@ -1,39 +1,24 @@
|
|
|
1
1
|
import { PLUGIN_RPC } from '@zhin.js/console-protocol';
|
|
2
|
+
/**
|
|
3
|
+
* Refusal of the global plugin switch (`plugin:set-enabled`, `feature.set-enabled` at `global`)
|
|
4
|
+
* by an instance: the switch is a gateway transaction (stop → write `disable_plugins` → start,
|
|
5
|
+
* rollback on failure) and is never written by the instance itself (ADR 0054 §4).
|
|
6
|
+
*/
|
|
7
|
+
export const PLUGIN_SWITCH_REQUIRES_GATEWAY = '插件全局启停由管理网关执行(停止实例 → 写入 disable_plugins → 启动,失败回滚):请在 zhin start 启动的 Console 中操作,或运行 zhin enable / zhin disable <插件>';
|
|
2
8
|
/**
|
|
3
9
|
* Dispatches the plugin-management slice; undefined means the type belongs elsewhere. Package
|
|
4
10
|
* installs / updates / uninstalls are not handled in the instance: they are gateway dependency
|
|
5
|
-
* transactions (`gateway.packages.*`, ADR 0054 §4) that stop the instance first
|
|
11
|
+
* transactions (`gateway.packages.*`, ADR 0054 §4) that stop the instance first, and so is the
|
|
12
|
+
* global plugin switch (`plugin:set-enabled`, refused here).
|
|
6
13
|
*/
|
|
7
14
|
export async function dispatchPluginConsoleRpc(type, message, ctx) {
|
|
8
15
|
const requestId = message.requestId;
|
|
9
16
|
try {
|
|
10
17
|
switch (type) {
|
|
11
|
-
case PLUGIN_RPC.SET_ENABLED:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return { requestId, error: 'instanceKey and boolean enabled are required' };
|
|
16
|
-
}
|
|
17
|
-
if (!ctx.setPluginEnabled) {
|
|
18
|
-
return { requestId, error: 'Plugin lifecycle management is not configured' };
|
|
19
|
-
}
|
|
20
|
-
const lifecycle = await ctx.setPluginEnabled(instanceKey, enabled);
|
|
21
|
-
ctx.publishEvent?.('plugin:lifecycle-updated', { instanceKey, enabled });
|
|
22
|
-
if (ctx.requestRestart) {
|
|
23
|
-
setTimeout(() => void Promise.resolve(ctx.requestRestart?.()).catch(() => undefined), 500);
|
|
24
|
-
}
|
|
25
|
-
return {
|
|
26
|
-
requestId,
|
|
27
|
-
data: {
|
|
28
|
-
success: true,
|
|
29
|
-
instanceKey,
|
|
30
|
-
enabled,
|
|
31
|
-
disabled: lifecycle.disabled,
|
|
32
|
-
restartRequired: true,
|
|
33
|
-
message: `${instanceKey} 已${enabled ? '启用' : '停用'},Host 正在重启`,
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
}
|
|
18
|
+
case PLUGIN_RPC.SET_ENABLED:
|
|
19
|
+
// Global plugin on / off is a management gateway transaction (ADR 0054 §4): the gateway
|
|
20
|
+
// answers it before forwarding. Reaching the instance means no gateway is in front.
|
|
21
|
+
return { requestId, error: PLUGIN_SWITCH_REQUIRES_GATEWAY };
|
|
37
22
|
case PLUGIN_RPC.INSPECT:
|
|
38
23
|
case PLUGIN_RPC.APPLY:
|
|
39
24
|
case PLUGIN_RPC.PLAN_VERIFICATION:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ConsoleAdapterLoginDeclaration, ConsoleLoginFlow, ConsoleLoginOutcome } from '@zhin.js/console-protocol';
|
|
1
2
|
interface LoginEndpointIdentity {
|
|
2
3
|
readonly canonicalId: string;
|
|
3
4
|
readonly instanceId: string;
|
|
@@ -20,27 +21,32 @@ export interface ConsoleRpcExtendedCtx {
|
|
|
20
21
|
};
|
|
21
22
|
/** Narrow generation-bound persistent-job port; null when Assistant is disabled. */
|
|
22
23
|
resolveScheduleEngine?: () => ConsoleScheduleEngine | null | undefined;
|
|
23
|
-
/** LoginAssist list/submit/cancel
|
|
24
|
-
loginAssist?:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
adapter: string;
|
|
28
|
-
endpointKey: string;
|
|
29
|
-
endpointIdentity?: LoginEndpointIdentity;
|
|
30
|
-
type: string;
|
|
31
|
-
payload: Record<string, unknown>;
|
|
32
|
-
createdAt: number;
|
|
33
|
-
expiresAt?: number;
|
|
34
|
-
}[];
|
|
35
|
-
submit(id: string, value: string | Record<string, unknown>, endpointIdentity?: LoginEndpointIdentity): boolean;
|
|
36
|
-
cancel(id: string, reason?: string, endpointIdentity?: LoginEndpointIdentity): boolean;
|
|
37
|
-
};
|
|
24
|
+
/** LoginAssist list/submit/cancel(刷新后仍可消费扫码/滑块待办);ADR 0058 flow methods are optional. */
|
|
25
|
+
loginAssist?: ConsoleLoginAssistPort;
|
|
26
|
+
/** ADR 0058: the Endpoint's login declaration and lease-scoped login control (`null` = unknown Endpoint). */
|
|
27
|
+
withEndpointLogin?: <T>(adapter: string, endpointKey: string, run: (login: ConsoleEndpointLoginAccess) => T | Promise<T>) => Promise<T | null>;
|
|
38
28
|
/** Authenticated Root adapter; mutation DTOs deliberately contain no principal/decision fields. */
|
|
39
29
|
workroomProfileControl?: ConsoleWorkroomProfileControlPort;
|
|
40
30
|
/** Authenticated HTTP principal; never accepted from the RPC body. */
|
|
41
31
|
authenticatedPrincipal?: Readonly<{
|
|
42
32
|
principalId: string;
|
|
43
33
|
}>;
|
|
34
|
+
/**
|
|
35
|
+
* The Endpoint the caller was authorized for when its grant covers this call only at an adapter /
|
|
36
|
+
* endpoint scope (never set for global grants, owners or in-process callers). Handlers that act on
|
|
37
|
+
* login tasks or flows restrict themselves to it; set by the dispatcher, never read from the body.
|
|
38
|
+
*/
|
|
39
|
+
authorizedEndpoint?: Readonly<{
|
|
40
|
+
adapter: string;
|
|
41
|
+
endpointKey: string;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* Whether the caller holds `endpoint.operate` on one Endpoint (set by the dispatcher from the
|
|
45
|
+
* authenticated principal, never read from the body). Login read RPCs return live challenge
|
|
46
|
+
* material (QR image, sensitive blocks, verification links, legacy `payload.image` / `url`) only
|
|
47
|
+
* when it says yes; absent (in-process callers without a principal) = trusted.
|
|
48
|
+
*/
|
|
49
|
+
canOperateEndpoint?: (adapter: string, endpointKey: string) => boolean;
|
|
44
50
|
workroomKnowledgeControl?: ConsoleWorkroomKnowledgeControlPort;
|
|
45
51
|
}
|
|
46
52
|
export interface ConsoleWorkroomProfileControlPort {
|
|
@@ -118,11 +124,60 @@ export interface ConsoleScheduleEngine {
|
|
|
118
124
|
resumeJob(id: string): Promise<boolean>;
|
|
119
125
|
listJobs(): Promise<Record<string, unknown>[]>;
|
|
120
126
|
}
|
|
127
|
+
/** `data` next to `error` carries a machine-readable code (e.g. `{ code: 'unsupported' }`). */
|
|
121
128
|
export type ExtendedRpcResult = {
|
|
122
129
|
data: unknown;
|
|
123
130
|
} | {
|
|
124
131
|
error: string;
|
|
132
|
+
data?: unknown;
|
|
125
133
|
};
|
|
134
|
+
/** Structural LoginAssist port (host/http must not import `@zhin.js/core`). */
|
|
135
|
+
export interface ConsoleLoginAssistPort {
|
|
136
|
+
listPending(): readonly {
|
|
137
|
+
id: string;
|
|
138
|
+
adapter: string;
|
|
139
|
+
endpointKey: string;
|
|
140
|
+
endpointIdentity?: LoginEndpointIdentity;
|
|
141
|
+
type: string;
|
|
142
|
+
payload: Record<string, unknown>;
|
|
143
|
+
createdAt: number;
|
|
144
|
+
expiresAt?: number;
|
|
145
|
+
flowId?: string;
|
|
146
|
+
challengeId?: string;
|
|
147
|
+
}[];
|
|
148
|
+
submit(id: string, value: string | Record<string, unknown>, endpointIdentity?: LoginEndpointIdentity): boolean;
|
|
149
|
+
cancel(id: string, reason?: string, endpointIdentity?: LoginEndpointIdentity): boolean;
|
|
150
|
+
/** ADR 0058 */
|
|
151
|
+
listFlows?(): readonly ConsoleLoginFlow[];
|
|
152
|
+
getFlow?(adapter: string, endpointKey: string): ConsoleLoginFlow | undefined;
|
|
153
|
+
getFlowById?(id: string): ConsoleLoginFlow | undefined;
|
|
154
|
+
/**
|
|
155
|
+
* Event-safe copy of a flow (core `withoutLoginMedia`): no QR image, sensitive blocks redacted,
|
|
156
|
+
* verification links dropped. Returned to readers without `endpoint.operate` on the flow's
|
|
157
|
+
* Endpoint; without it the host strips every challenge's media and blocks.
|
|
158
|
+
*/
|
|
159
|
+
eventSafeFlow?(flow: ConsoleLoginFlow): ConsoleLoginFlow;
|
|
160
|
+
submitAndWait?(id: string, value: string | Record<string, unknown>, options?: {
|
|
161
|
+
endpointIdentity?: LoginEndpointIdentity;
|
|
162
|
+
timeoutMs?: number;
|
|
163
|
+
}): Promise<{
|
|
164
|
+
accepted: boolean;
|
|
165
|
+
outcome?: ConsoleLoginOutcome;
|
|
166
|
+
pending?: boolean;
|
|
167
|
+
flow?: ConsoleLoginFlow;
|
|
168
|
+
}>;
|
|
169
|
+
}
|
|
170
|
+
export interface ConsoleEndpointLoginAccess {
|
|
171
|
+
readonly declaration?: ConsoleAdapterLoginDeclaration;
|
|
172
|
+
readonly control?: {
|
|
173
|
+
relogin?(request: {
|
|
174
|
+
signal?: AbortSignal;
|
|
175
|
+
}): Promise<void>;
|
|
176
|
+
refreshChallenge?(request: {
|
|
177
|
+
signal?: AbortSignal;
|
|
178
|
+
}): Promise<void>;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
126
181
|
export interface ScheduleJobRow {
|
|
127
182
|
id: string;
|
|
128
183
|
cron: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { addCron, listSchedule, mutateCron, validateCron } from './schedule-rpc.js';
|
|
2
2
|
import { actOnRequest, listInbox, listInboxMessages, listPendingRequests, listRecentInboxMessages, mapNoticeRow, mapRequestRow, markInboxConsumed, TABLE_NOTICE, TABLE_REQUEST, } from './inbox-rpc.js';
|
|
3
|
-
import { cancelLogin, listLoginPending, submitLogin } from './login-rpc.js';
|
|
3
|
+
import { cancelLogin, controlLogin, getLoginFlow, listLoginFlows, listLoginPending, submitLogin } from './login-rpc.js';
|
|
4
4
|
import { deleteFriend, groupWriteOp, listChannels, listFriends, listGroupMembers, listGroups, } from './endpoint-rpc.js';
|
|
5
5
|
import { mutateWorkroomKnowledge, mutateWorkroomProfile } from './workroom-rpc.js';
|
|
6
6
|
export async function dispatchExtendedConsoleRpc(type, data, ctx) {
|
|
@@ -32,11 +32,18 @@ export async function dispatchExtendedConsoleRpc(type, data, ctx) {
|
|
|
32
32
|
case 'request.reject':
|
|
33
33
|
return actOnRequest(type, d, ctx);
|
|
34
34
|
case 'login.list':
|
|
35
|
-
return listLoginPending(ctx);
|
|
35
|
+
return listLoginPending(d, ctx);
|
|
36
36
|
case 'login.submit':
|
|
37
37
|
return submitLogin(d, ctx);
|
|
38
38
|
case 'login.cancel':
|
|
39
39
|
return cancelLogin(d, ctx);
|
|
40
|
+
case 'login.flow.list':
|
|
41
|
+
return listLoginFlows(d, ctx);
|
|
42
|
+
case 'login.flow.get':
|
|
43
|
+
return getLoginFlow(d, ctx);
|
|
44
|
+
case 'login.relogin':
|
|
45
|
+
case 'login.refresh':
|
|
46
|
+
return controlLogin(type, d, ctx);
|
|
40
47
|
case 'request.consumed':
|
|
41
48
|
return markInboxConsumed(d, ctx, TABLE_REQUEST);
|
|
42
49
|
case 'notice.consumed':
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export type { ConsoleRpcExtendedCtx, ConsoleScheduleEngine, ConsoleWorkroomKnowledgeControlPort, ConsoleWorkroomProfileControlPort, ExtendedRpcResult, } from './contracts.js';
|
|
1
|
+
export type { ConsoleRpcExtendedCtx, ConsoleScheduleEngine, ConsoleWorkroomKnowledgeControlPort, ConsoleWorkroomProfileControlPort, ExtendedRpcResult, ConsoleLoginAssistPort, ConsoleEndpointLoginAccess, } from './contracts.js';
|
|
2
|
+
export { loginAuditDetail, LOGIN_SUBMIT_WAIT_MS } from './login-rpc.js';
|
|
2
3
|
export { dispatchExtendedConsoleRpc } from './dispatcher.js';
|
|
@@ -1,4 +1,27 @@
|
|
|
1
|
+
import { LOGIN_RPC } from '@zhin.js/console-protocol';
|
|
1
2
|
import type { ConsoleRpcExtendedCtx, ExtendedRpcResult } from './contracts.js';
|
|
2
|
-
|
|
3
|
-
export declare
|
|
3
|
+
/** `login.submit` with `wait: true` waits at most this long for the login result. */
|
|
4
|
+
export declare const LOGIN_SUBMIT_WAIT_MS = 15000;
|
|
5
|
+
export declare function listLoginPending(d: Record<string, unknown>, ctx: ConsoleRpcExtendedCtx): ExtendedRpcResult;
|
|
6
|
+
/**
|
|
7
|
+
* `login.submit { taskId, value, endpointIdentity?, adapter?, endpointKey?, wait? }`.
|
|
8
|
+
* `value` is a string (legacy) or `{ action, values }`. With `wait: true` the reply carries the login
|
|
9
|
+
* result (`{ accepted, outcome, flow }`) or `{ accepted, pending: true }` after 15 s; without it the
|
|
10
|
+
* legacy `{ success: true }` reply is unchanged.
|
|
11
|
+
*/
|
|
12
|
+
export declare function submitLogin(d: Record<string, unknown>, ctx: ConsoleRpcExtendedCtx): Promise<ExtendedRpcResult>;
|
|
4
13
|
export declare function cancelLogin(d: Record<string, unknown>, ctx: ConsoleRpcExtendedCtx): ExtendedRpcResult;
|
|
14
|
+
/**
|
|
15
|
+
* `login.flow.list { adapter?, endpointKey? }`: latest flow per Endpoint. Live challenge material
|
|
16
|
+
* only for Endpoints the caller may operate; the event-safe form otherwise (ADR 0058 §8).
|
|
17
|
+
*/
|
|
18
|
+
export declare function listLoginFlows(d: Record<string, unknown>, ctx: ConsoleRpcExtendedCtx): ExtendedRpcResult;
|
|
19
|
+
/** `login.flow.get { flowId } | { adapter, endpointKey }` → `{ flow: … | null }`. */
|
|
20
|
+
export declare function getLoginFlow(d: Record<string, unknown>, ctx: ConsoleRpcExtendedCtx): ExtendedRpcResult;
|
|
21
|
+
/** `login.relogin` / `login.refresh { adapter, endpointKey }` through the Endpoint's login port. */
|
|
22
|
+
export declare function controlLogin(type: typeof LOGIN_RPC.RELOGIN | typeof LOGIN_RPC.REFRESH, d: Record<string, unknown>, ctx: ConsoleRpcExtendedCtx): Promise<ExtendedRpcResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Audit detail of a login RPC reply: the result category only (never values, never messages).
|
|
25
|
+
* `undefined` for other RPCs.
|
|
26
|
+
*/
|
|
27
|
+
export declare function loginAuditDetail(type: unknown, data: unknown): Readonly<Record<string, string>> | undefined;
|