@harrylabsj/kiwi 0.8.0 → 0.10.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/README.md +1 -1
- package/dist/a2a/negotiate.d.ts +6 -2
- package/dist/a2a/negotiate.js +10 -3
- package/dist/a2a/negotiate.js.map +1 -1
- package/dist/a2a/node.d.ts +4 -1
- package/dist/a2a/node.js +56 -3
- package/dist/a2a/node.js.map +1 -1
- package/dist/a2a/server/merchant-handler.d.ts +11 -3
- package/dist/a2a/server/merchant-handler.js +84 -26
- package/dist/a2a/server/merchant-handler.js.map +1 -1
- package/dist/agent/buyer/buyer-tools.js +2 -2
- package/dist/agent/buyer/buyer-tools.js.map +1 -1
- package/dist/agent/kernel.js +5 -1
- package/dist/agent/kernel.js.map +1 -1
- package/dist/agent/memory/schema.d.ts +1 -1
- package/dist/agent/memory/schema.js +9 -1
- package/dist/agent/memory/schema.js.map +1 -1
- package/dist/agent/merchant/action-candidate.d.ts +18 -0
- package/dist/agent/merchant/action-candidate.js +51 -0
- package/dist/agent/merchant/action-candidate.js.map +1 -1
- package/dist/agent/merchant/fake-merchant-client.js +6 -1
- package/dist/agent/merchant/fake-merchant-client.js.map +1 -1
- package/dist/agent/merchant/intelligence/default-backend.js +25 -2
- package/dist/agent/merchant/intelligence/default-backend.js.map +1 -1
- package/dist/agent/merchant/merchant-client.d.ts +50 -1
- package/dist/agent/merchant/merchant-client.js +157 -8
- package/dist/agent/merchant/merchant-client.js.map +1 -1
- package/dist/agent/merchant/merchant-presentations.js +25 -2
- package/dist/agent/merchant/merchant-presentations.js.map +1 -1
- package/dist/agent/merchant/merchant-tools.js +102 -188
- package/dist/agent/merchant/merchant-tools.js.map +1 -1
- package/dist/agent/merchant/types.d.ts +6 -2
- package/dist/agent/merchant/types.js +45 -0
- package/dist/agent/merchant/types.js.map +1 -1
- package/dist/auth/merchant-authorization.d.ts +49 -0
- package/dist/auth/merchant-authorization.js +61 -0
- package/dist/auth/merchant-authorization.js.map +1 -0
- package/dist/auth/merchant-oauth.d.ts +255 -0
- package/dist/auth/merchant-oauth.js +764 -0
- package/dist/auth/merchant-oauth.js.map +1 -0
- package/dist/auth/merchant-pairing.d.ts +62 -0
- package/dist/auth/merchant-pairing.js +199 -0
- package/dist/auth/merchant-pairing.js.map +1 -0
- package/dist/auth/merchant-sessions.d.ts +71 -0
- package/dist/auth/merchant-sessions.js +168 -0
- package/dist/auth/merchant-sessions.js.map +1 -0
- package/dist/buyer-core/build-service.d.ts +5 -0
- package/dist/buyer-core/build-service.js +12 -0
- package/dist/buyer-core/build-service.js.map +1 -1
- package/dist/buyer-core/errors.d.ts +1 -1
- package/dist/buyer-core/errors.js +2 -0
- package/dist/buyer-core/errors.js.map +1 -1
- package/dist/buyer-core/merchant-index.d.ts +19 -4
- package/dist/buyer-core/merchant-index.js +137 -16
- package/dist/buyer-core/merchant-index.js.map +1 -1
- package/dist/buyer-core/negotiator.d.ts +0 -10
- package/dist/buyer-core/negotiator.js +12 -1
- package/dist/buyer-core/negotiator.js.map +1 -1
- package/dist/buyer-core/quote-fetcher.js +2 -1
- package/dist/buyer-core/quote-fetcher.js.map +1 -1
- package/dist/buyer-core/service.d.ts +104 -0
- package/dist/buyer-core/service.js +105 -1
- package/dist/buyer-core/service.js.map +1 -1
- package/dist/cli.d.ts +4 -2
- package/dist/cli.js +612 -20
- package/dist/cli.js.map +1 -1
- package/dist/config/profile.d.ts +30 -0
- package/dist/config/profile.js +126 -61
- package/dist/config/profile.js.map +1 -1
- package/dist/demo/demo-runner.js +12 -9
- package/dist/demo/demo-runner.js.map +1 -1
- package/dist/discovery/catalog-source/buyer-follows.d.ts +82 -0
- package/dist/discovery/catalog-source/buyer-follows.js +228 -0
- package/dist/discovery/catalog-source/buyer-follows.js.map +1 -0
- package/dist/discovery/catalog-source/connector-identity.d.ts +75 -0
- package/dist/discovery/catalog-source/connector-identity.js +175 -0
- package/dist/discovery/catalog-source/connector-identity.js.map +1 -0
- package/dist/discovery/catalog-source/errors.d.ts +1 -1
- package/dist/discovery/catalog-source/errors.js +2 -0
- package/dist/discovery/catalog-source/errors.js.map +1 -1
- package/dist/discovery/catalog-source/merchant-publications.d.ts +65 -0
- package/dist/discovery/catalog-source/merchant-publications.js +207 -0
- package/dist/discovery/catalog-source/merchant-publications.js.map +1 -0
- package/dist/discovery/catalog-source/register.d.ts +24 -0
- package/dist/discovery/catalog-source/register.js +46 -0
- package/dist/discovery/catalog-source/register.js.map +1 -1
- package/dist/discovery/catalog-source/source.js +2 -1
- package/dist/discovery/catalog-source/source.js.map +1 -1
- package/dist/fs/atomic-write.d.ts +18 -0
- package/dist/fs/atomic-write.js +29 -0
- package/dist/fs/atomic-write.js.map +1 -0
- package/dist/http/server.js +4 -1
- package/dist/http/server.js.map +1 -1
- package/dist/mcp/cli.d.ts +2 -0
- package/dist/mcp/cli.js +7 -6
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/merchant-auth.d.ts +78 -0
- package/dist/mcp/merchant-auth.js +146 -0
- package/dist/mcp/merchant-auth.js.map +1 -0
- package/dist/mcp/merchant-dirs.d.ts +26 -0
- package/dist/mcp/merchant-dirs.js +44 -0
- package/dist/mcp/merchant-dirs.js.map +1 -0
- package/dist/mcp/merchant-resources.d.ts +38 -0
- package/dist/mcp/merchant-resources.js +146 -0
- package/dist/mcp/merchant-resources.js.map +1 -0
- package/dist/mcp/merchant-server.d.ts +106 -0
- package/dist/mcp/merchant-server.js +615 -0
- package/dist/mcp/merchant-server.js.map +1 -0
- package/dist/mcp/merchant-tools.d.ts +103 -0
- package/dist/mcp/merchant-tools.js +517 -0
- package/dist/mcp/merchant-tools.js.map +1 -0
- package/dist/mcp/server.js +4 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +5 -3
- package/dist/mcp/tools.js +102 -5
- package/dist/mcp/tools.js.map +1 -1
- package/dist/mcp/types.d.ts +1 -1
- package/dist/mcp/types.js +4 -0
- package/dist/mcp/types.js.map +1 -1
- package/dist/merchant/ops.d.ts +0 -11
- package/dist/merchant/ops.js +13 -1
- package/dist/merchant/ops.js.map +1 -1
- package/dist/merchant/workbench-service.d.ts +189 -0
- package/dist/merchant/workbench-service.js +417 -0
- package/dist/merchant/workbench-service.js.map +1 -0
- package/dist/merchant-admin/pending-page.d.ts +35 -0
- package/dist/merchant-admin/pending-page.js +69 -0
- package/dist/merchant-admin/pending-page.js.map +1 -0
- package/dist/merchant-core/commands.d.ts +99 -0
- package/dist/merchant-core/commands.js +179 -0
- package/dist/merchant-core/commands.js.map +1 -0
- package/dist/merchant-core/executor.d.ts +69 -0
- package/dist/merchant-core/executor.js +218 -0
- package/dist/merchant-core/executor.js.map +1 -0
- package/dist/merchant-core/negotiation-adapters.d.ts +55 -0
- package/dist/merchant-core/negotiation-adapters.js +55 -0
- package/dist/merchant-core/negotiation-adapters.js.map +1 -0
- package/dist/merchant-core/network-checks.d.ts +65 -0
- package/dist/merchant-core/network-checks.js +111 -0
- package/dist/merchant-core/network-checks.js.map +1 -0
- package/dist/merchant-core/operations.d.ts +64 -0
- package/dist/merchant-core/operations.js +136 -0
- package/dist/merchant-core/operations.js.map +1 -0
- package/dist/merchant-core/policy-runtime.d.ts +70 -0
- package/dist/merchant-core/policy-runtime.js +181 -0
- package/dist/merchant-core/policy-runtime.js.map +1 -0
- package/dist/merchant-core/product-import.d.ts +67 -0
- package/dist/merchant-core/product-import.js +160 -0
- package/dist/merchant-core/product-import.js.map +1 -0
- package/dist/merchant-core/service.d.ts +203 -0
- package/dist/merchant-core/service.js +402 -0
- package/dist/merchant-core/service.js.map +1 -0
- package/dist/merchant-gateway/catalog-publications.d.ts +96 -0
- package/dist/merchant-gateway/catalog-publications.js +212 -0
- package/dist/merchant-gateway/catalog-publications.js.map +1 -0
- package/dist/merchant-gateway/catalog-tools.d.ts +46 -0
- package/dist/merchant-gateway/catalog-tools.js +315 -0
- package/dist/merchant-gateway/catalog-tools.js.map +1 -0
- package/dist/merchant-gateway/cli.d.ts +75 -0
- package/dist/merchant-gateway/cli.js +461 -0
- package/dist/merchant-gateway/cli.js.map +1 -0
- package/dist/merchant-gateway/credential-vault.d.ts +44 -0
- package/dist/merchant-gateway/credential-vault.js +111 -0
- package/dist/merchant-gateway/credential-vault.js.map +1 -0
- package/dist/merchant-gateway/entry-server.d.ts +117 -0
- package/dist/merchant-gateway/entry-server.js +747 -0
- package/dist/merchant-gateway/entry-server.js.map +1 -0
- package/dist/merchant-gateway/instance-registration.d.ts +144 -0
- package/dist/merchant-gateway/instance-registration.js +391 -0
- package/dist/merchant-gateway/instance-registration.js.map +1 -0
- package/dist/merchant-gateway/instance-tools.d.ts +58 -0
- package/dist/merchant-gateway/instance-tools.js +186 -0
- package/dist/merchant-gateway/instance-tools.js.map +1 -0
- package/dist/merchant-gateway/mcp-proxy.d.ts +25 -0
- package/dist/merchant-gateway/mcp-proxy.js +192 -0
- package/dist/merchant-gateway/mcp-proxy.js.map +1 -0
- package/dist/merchant-gateway/pinned-fetch.d.ts +54 -0
- package/dist/merchant-gateway/pinned-fetch.js +231 -0
- package/dist/merchant-gateway/pinned-fetch.js.map +1 -0
- package/dist/merchant-gateway/tenant-registry.d.ts +82 -0
- package/dist/merchant-gateway/tenant-registry.js +190 -0
- package/dist/merchant-gateway/tenant-registry.js.map +1 -0
- package/dist/merchant-gateway/tool-bundle.d.ts +26 -0
- package/dist/merchant-gateway/tool-bundle.js +56 -0
- package/dist/merchant-gateway/tool-bundle.js.map +1 -0
- package/dist/merchant-runtime/backup.d.ts +48 -0
- package/dist/merchant-runtime/backup.js +226 -0
- package/dist/merchant-runtime/backup.js.map +1 -0
- package/dist/merchant-runtime/health.d.ts +99 -0
- package/dist/merchant-runtime/health.js +206 -0
- package/dist/merchant-runtime/health.js.map +1 -0
- package/dist/merchant-runtime/jobs.d.ts +64 -0
- package/dist/merchant-runtime/jobs.js +107 -0
- package/dist/merchant-runtime/jobs.js.map +1 -0
- package/dist/merchant-runtime/manager.d.ts +94 -0
- package/dist/merchant-runtime/manager.js +305 -0
- package/dist/merchant-runtime/manager.js.map +1 -0
- package/dist/merchant-runtime/services.d.ts +30 -0
- package/dist/merchant-runtime/services.js +51 -0
- package/dist/merchant-runtime/services.js.map +1 -0
- package/dist/net/url.d.ts +26 -0
- package/dist/net/url.js +32 -0
- package/dist/net/url.js.map +1 -0
- package/dist/product-cli.js +22 -3
- package/dist/product-cli.js.map +1 -1
- package/dist/product-compat.d.ts +9 -1
- package/dist/product-compat.js +12 -1
- package/dist/product-compat.js.map +1 -1
- package/dist/product-init.js +17 -5
- package/dist/product-init.js.map +1 -1
- package/dist/product-publish.js +2 -1
- package/dist/product-publish.js.map +1 -1
- package/package.json +3 -2
- package/skills/kiwi-buyer/SKILL.md +2 -0
|
@@ -64,6 +64,51 @@ export function parseMerchantCatalogProduct(value) {
|
|
|
64
64
|
handoff_destination: typeof v.handoff_destination === "string" ? v.handoff_destination : undefined,
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* 解析商品创建入参(白名单 + 类型校验;MCP/命令面共用)。merchant_id 强制
|
|
69
|
+
* 归属商家:缺省补 ownerId,传入不一致直接拒绝(防跨租户写)。非数值/负数
|
|
70
|
+
* price、负数或非整数 stock 一律拒绝——审批前的 prepare 即失败,不烧人工确认。
|
|
71
|
+
*/
|
|
72
|
+
export function parseProductCreateInput(value, ownerId) {
|
|
73
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
74
|
+
throw new TypeError("product 必须是对象");
|
|
75
|
+
}
|
|
76
|
+
const v = value;
|
|
77
|
+
const merchantId = typeof v.merchant_id === "string" && v.merchant_id !== "" ? v.merchant_id : ownerId;
|
|
78
|
+
if (merchantId !== ownerId) {
|
|
79
|
+
throw new TypeError(`product.merchant_id 与本实例商家不一致(不允许跨商家创建)`);
|
|
80
|
+
}
|
|
81
|
+
const sku = typeof v.sku === "string" ? v.sku.trim() : "";
|
|
82
|
+
if (sku === "")
|
|
83
|
+
throw new TypeError("product.sku 必须是非空字符串");
|
|
84
|
+
const title = typeof v.title === "string" ? v.title.trim() : "";
|
|
85
|
+
if (title === "")
|
|
86
|
+
throw new TypeError("product.title 必须是非空字符串");
|
|
87
|
+
if (typeof v.price !== "number" || !Number.isFinite(v.price) || v.price < 0) {
|
|
88
|
+
throw new TypeError("product.price 必须是非负有限数值");
|
|
89
|
+
}
|
|
90
|
+
if (typeof v.stock !== "number" || !Number.isInteger(v.stock) || v.stock < 0) {
|
|
91
|
+
throw new TypeError("product.stock 必须是非负整数");
|
|
92
|
+
}
|
|
93
|
+
const input = {
|
|
94
|
+
merchant_id: merchantId,
|
|
95
|
+
sku,
|
|
96
|
+
title,
|
|
97
|
+
price: v.price,
|
|
98
|
+
stock: v.stock,
|
|
99
|
+
};
|
|
100
|
+
if (typeof v.currency === "string" && v.currency !== "")
|
|
101
|
+
input.currency = v.currency;
|
|
102
|
+
if (typeof v.category === "string" && v.category !== "")
|
|
103
|
+
input.category = v.category;
|
|
104
|
+
if (typeof v.description === "string")
|
|
105
|
+
input.description = v.description;
|
|
106
|
+
if (Array.isArray(v.tags))
|
|
107
|
+
input.tags = stringArray(v.tags, "product.tags");
|
|
108
|
+
if (Array.isArray(v.delivery_attributes))
|
|
109
|
+
input.delivery_attributes = stringArray(v.delivery_attributes, "product.delivery_attributes");
|
|
110
|
+
return input;
|
|
111
|
+
}
|
|
67
112
|
export function parseInventorySnapshot(value, sku) {
|
|
68
113
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
69
114
|
fail("inventory snapshot must be an object");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/agent/merchant/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/agent/merchant/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 harrylabsj
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Merchant MCP 的 OAuth 授权校验(V2 阶段一)。
|
|
18
|
+
*
|
|
19
|
+
* 在 MerchantMcpAuthVerifier 接缝上叠加 OAuth Bearer 校验:access_token 查
|
|
20
|
+
* 授权服务器 store(签发方本服务、有效期、未撤销),并返回 principal/scope
|
|
21
|
+
* 授权上下文。租户隔离(前置决策 3):token 在签发时绑定 merchant_id,校验
|
|
22
|
+
* 时必须等于本实例的 expectedMerchantId——用户参数不能选择任意 merchant_id,
|
|
23
|
+
* 跨商家访问一律拒绝。
|
|
24
|
+
*
|
|
25
|
+
* scope 设计:merchant:read(只读工具)/ merchant:write(写类工具,本轮仅
|
|
26
|
+
* 审批候选生成)。本轮接入校验;tools/list 按 scope 过滤留给后续波次。
|
|
27
|
+
*/
|
|
28
|
+
import type { MerchantOAuthStore } from "./merchant-oauth.js";
|
|
29
|
+
import type { MerchantMcpAuthContext, MerchantMcpAuthResult, MerchantMcpAuthVerifier } from "../mcp/merchant-auth.js";
|
|
30
|
+
/** 本服务支持的 scope(读/写两类;写类工具要求 merchant:write)。 */
|
|
31
|
+
export declare const MERCHANT_OAUTH_SCOPES: readonly ["merchant:read", "merchant:write"];
|
|
32
|
+
export type MerchantOAuthScope = (typeof MERCHANT_OAUTH_SCOPES)[number];
|
|
33
|
+
/** 校验通过的授权上下文(principal/merchant/scope;供 tools 过滤与审计)。 */
|
|
34
|
+
export interface MerchantAuthorization {
|
|
35
|
+
principal_id: string;
|
|
36
|
+
merchant_id: string;
|
|
37
|
+
scopes: string[];
|
|
38
|
+
}
|
|
39
|
+
export declare class MerchantOAuthVerifier implements MerchantMcpAuthVerifier {
|
|
40
|
+
readonly name = "oauth-bearer";
|
|
41
|
+
private readonly store;
|
|
42
|
+
private readonly expectedMerchantId;
|
|
43
|
+
constructor(options: {
|
|
44
|
+
store: MerchantOAuthStore;
|
|
45
|
+
expectedMerchantId?: string;
|
|
46
|
+
multiMerchant?: boolean;
|
|
47
|
+
});
|
|
48
|
+
verify(ctx: MerchantMcpAuthContext): MerchantMcpAuthResult;
|
|
49
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 harrylabsj
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/** 本服务支持的 scope(读/写两类;写类工具要求 merchant:write)。 */
|
|
17
|
+
export const MERCHANT_OAUTH_SCOPES = ["merchant:read", "merchant:write"];
|
|
18
|
+
export class MerchantOAuthVerifier {
|
|
19
|
+
name = "oauth-bearer";
|
|
20
|
+
store;
|
|
21
|
+
expectedMerchantId;
|
|
22
|
+
constructor(options) {
|
|
23
|
+
if (options.multiMerchant === true) {
|
|
24
|
+
if (options.expectedMerchantId !== undefined) {
|
|
25
|
+
throw new Error("通用 OAuth 校验器不能同时固定 expectedMerchantId");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else if (!options.expectedMerchantId) {
|
|
29
|
+
throw new Error("单商家 OAuth 校验器必须配置 expectedMerchantId;通用网关须显式 multiMerchant=true");
|
|
30
|
+
}
|
|
31
|
+
this.store = options.store;
|
|
32
|
+
this.expectedMerchantId = options.expectedMerchantId;
|
|
33
|
+
}
|
|
34
|
+
verify(ctx) {
|
|
35
|
+
const header = ctx.authorizationHeader;
|
|
36
|
+
if (header === undefined || header === "") {
|
|
37
|
+
return { ok: false, reason: "missing Authorization header" };
|
|
38
|
+
}
|
|
39
|
+
const match = /^Bearer\s+(.+)$/i.exec(header.trim());
|
|
40
|
+
if (match === null) {
|
|
41
|
+
return { ok: false, reason: "Authorization header is not a bearer token" };
|
|
42
|
+
}
|
|
43
|
+
const token = this.store.getAccessToken(match[1] ?? "");
|
|
44
|
+
if (token === undefined) {
|
|
45
|
+
return { ok: false, reason: "invalid or expired access token" };
|
|
46
|
+
}
|
|
47
|
+
// 租户校验(前置决策 3):token 签发给哪个商家就只能访问哪个商家。
|
|
48
|
+
if (this.expectedMerchantId !== undefined && token.merchant_id !== this.expectedMerchantId) {
|
|
49
|
+
return { ok: false, reason: "token merchant 不属于本实例(租户越权拒绝)" };
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
ok: true,
|
|
53
|
+
authorization: {
|
|
54
|
+
principal_id: token.principal_id,
|
|
55
|
+
merchant_id: token.merchant_id,
|
|
56
|
+
scopes: token.scope,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=merchant-authorization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merchant-authorization.js","sourceRoot":"","sources":["../../src/auth/merchant-authorization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAsBH,iDAAiD;AACjD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,eAAe,EAAE,gBAAgB,CAAU,CAAC;AAUlF,MAAM,OAAO,qBAAqB;IACvB,IAAI,GAAG,cAAc,CAAC;IACd,KAAK,CAAqB;IAC1B,kBAAkB,CAAqB;IAExD,YAAY,OAA4F;QACtG,IAAI,OAAO,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;YACnC,IAAI,OAAO,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;gBAC7C,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACrF,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,GAA2B;QAChC,MAAM,MAAM,GAAG,GAAG,CAAC,mBAAmB,CAAC;QACvC,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;YAC1C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC;QAC/D,CAAC;QACD,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACrD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,4CAA4C,EAAE,CAAC;QAC7E,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAC;QAClE,CAAC;QACD,uCAAuC;QACvC,IAAI,IAAI,CAAC,kBAAkB,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC3F,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC;QAChE,CAAC;QACD,OAAO;YACL,EAAE,EAAE,IAAI;YACR,aAAa,EAAE;gBACb,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,MAAM,EAAE,KAAK,CAAC,KAAK;aACpB;SACF,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 harrylabsj
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import type { DatabaseSync } from "node:sqlite";
|
|
17
|
+
/** 授权码有效期(10 分钟,一次性使用)。 */
|
|
18
|
+
export declare const OAUTH_CODE_TTL_MS: number;
|
|
19
|
+
/** access_token 有效期(1 小时)。 */
|
|
20
|
+
export declare const OAUTH_ACCESS_TOKEN_TTL_MS: number;
|
|
21
|
+
/** refresh_token 有效期(30 天)。 */
|
|
22
|
+
export declare const OAUTH_REFRESH_TOKEN_TTL_MS: number;
|
|
23
|
+
/** 授权请求(授权页挂起单)有效期(10 分钟)。 */
|
|
24
|
+
export declare const OAUTH_AUTH_REQUEST_TTL_MS: number;
|
|
25
|
+
/** WorkBuddy 私有协议回调(source 占位替换为实际连接器 source)。 */
|
|
26
|
+
export declare function workbuddyCallbackUri(source: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* OAuth 回调策略(可配置:source、期望回调与 loopback 回退都随部署确定)。
|
|
29
|
+
*
|
|
30
|
+
* - ``expectedCallbackUri``:显式期望的回调地址;缺省按连接器 source 派生
|
|
31
|
+
* WorkBuddy 私有协议回调(`workbuddy://…/connector%3A<source>/oauth/callback`)。
|
|
32
|
+
* 平台侧回调规则未实机核验前,保持“由 source 派生”即可;核验后如平台给出
|
|
33
|
+
* 不同形式,用本项覆盖而不改代码;
|
|
34
|
+
* - ``allowLoopbackFallback``:私有协议回调被平台拒绝时是否允许 http loopback
|
|
35
|
+
* 回退(官方文档的回退路径)。缺省 true;如需严格锁定为单一回调可置 false。
|
|
36
|
+
*/
|
|
37
|
+
export interface OAuthCallbackPolicy {
|
|
38
|
+
expectedCallbackUri?: string;
|
|
39
|
+
allowLoopbackFallback?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/** 解析生效的期望回调地址(显式配置优先,否则按 source 派生)。 */
|
|
42
|
+
export declare function expectedCallbackUri(connectorSource: string, policy?: OAuthCallbackPolicy): string;
|
|
43
|
+
/** redirect_uri 白名单判定:期望回调(source 派生或显式配置) 或 http loopback 回退。 */
|
|
44
|
+
export declare function isAllowedRedirectUri(uri: string, connectorSource: string, policy?: OAuthCallbackPolicy): boolean;
|
|
45
|
+
/** 端点处理结果:JSON body / HTML 页面 / 302 重定向。 */
|
|
46
|
+
export type OAuthHttpResult = {
|
|
47
|
+
status: number;
|
|
48
|
+
body?: unknown;
|
|
49
|
+
html?: string;
|
|
50
|
+
headers?: Record<string, string>;
|
|
51
|
+
};
|
|
52
|
+
/** PKCE S256:base64url(sha256(verifier))。 */
|
|
53
|
+
export declare function pkceS256(verifier: string): string;
|
|
54
|
+
export interface OAuthClientRow {
|
|
55
|
+
client_id: string;
|
|
56
|
+
client_name: string | null;
|
|
57
|
+
redirect_uris: string[];
|
|
58
|
+
created_at: string;
|
|
59
|
+
}
|
|
60
|
+
export interface OAuthTokenRow {
|
|
61
|
+
client_id: string;
|
|
62
|
+
principal_id: string;
|
|
63
|
+
merchant_id: string;
|
|
64
|
+
scope: string[];
|
|
65
|
+
expires_at: string;
|
|
66
|
+
revoked_at: string | null;
|
|
67
|
+
created_at: string;
|
|
68
|
+
}
|
|
69
|
+
export declare class MerchantOAuthStore {
|
|
70
|
+
private readonly db;
|
|
71
|
+
private readonly now;
|
|
72
|
+
constructor(options: {
|
|
73
|
+
db: DatabaseSync;
|
|
74
|
+
now?: () => string;
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* 过期行清理(审查 P2:此前全库只增不删,长期运行单调膨胀)。只删完全
|
|
78
|
+
* 失效的行:挂起单/授权码/一次性凭证按各自 expires_at;token 需 access
|
|
79
|
+
* 与 refresh 双过期(撤销行在 refresh 未过期前保留可查)。
|
|
80
|
+
*/
|
|
81
|
+
cleanupExpired(): void;
|
|
82
|
+
private isoAfter;
|
|
83
|
+
private expired;
|
|
84
|
+
registerClient(input: {
|
|
85
|
+
client_name?: string;
|
|
86
|
+
redirect_uris: string[];
|
|
87
|
+
}): OAuthClientRow;
|
|
88
|
+
getClient(clientId: string): OAuthClientRow | undefined;
|
|
89
|
+
createAuthRequest(input: {
|
|
90
|
+
client_id: string;
|
|
91
|
+
redirect_uri: string;
|
|
92
|
+
scope: string;
|
|
93
|
+
state?: string;
|
|
94
|
+
code_challenge: string;
|
|
95
|
+
merchant_id: string;
|
|
96
|
+
/** 认证主体(BUG-01:来自管理登录会话,不是启动参数)。 */
|
|
97
|
+
principal_id: string;
|
|
98
|
+
}): string;
|
|
99
|
+
/** 取出并删除(一次性;过期或缺认证主体(迁移老数据)视为不存在)。 */
|
|
100
|
+
consumeAuthRequest(csrf: string): {
|
|
101
|
+
client_id: string;
|
|
102
|
+
redirect_uri: string;
|
|
103
|
+
scope: string;
|
|
104
|
+
state?: string;
|
|
105
|
+
code_challenge: string;
|
|
106
|
+
merchant_id: string;
|
|
107
|
+
principal_id: string;
|
|
108
|
+
} | undefined;
|
|
109
|
+
createCode(input: {
|
|
110
|
+
client_id: string;
|
|
111
|
+
redirect_uri: string;
|
|
112
|
+
scope: string;
|
|
113
|
+
principal_id: string;
|
|
114
|
+
merchant_id: string;
|
|
115
|
+
code_challenge: string;
|
|
116
|
+
}): string;
|
|
117
|
+
/** 核销授权码(一次性;过期/已用返回 undefined)。事务 + 条件更新:与
|
|
118
|
+
* rotateRefreshToken 同口径,双进程误开同一 oauth.sqlite 时同一授权码也
|
|
119
|
+
* 只能被核销一次(审查 P2:原 SELECT→UPDATE 无原子性)。 */
|
|
120
|
+
consumeCode(code: string): {
|
|
121
|
+
client_id: string;
|
|
122
|
+
redirect_uri: string;
|
|
123
|
+
scope: string;
|
|
124
|
+
principal_id: string;
|
|
125
|
+
merchant_id: string;
|
|
126
|
+
code_challenge: string;
|
|
127
|
+
} | undefined;
|
|
128
|
+
issueTokenPair(input: {
|
|
129
|
+
client_id: string;
|
|
130
|
+
principal_id: string;
|
|
131
|
+
merchant_id: string;
|
|
132
|
+
scope: string;
|
|
133
|
+
}): {
|
|
134
|
+
access_token: string;
|
|
135
|
+
refresh_token: string;
|
|
136
|
+
expires_in: number;
|
|
137
|
+
};
|
|
138
|
+
/** 查 access token(未过期、未撤销才返回)。 */
|
|
139
|
+
getAccessToken(accessToken: string): OAuthTokenRow | undefined;
|
|
140
|
+
/**
|
|
141
|
+
* 刷新轮换(BUG-10):同一事务内验证旧 refresh 未撤销、未过期(独立
|
|
142
|
+
* refresh_expires_at)并核销,再签发新 token 对——并发轮换只有一个成功
|
|
143
|
+
* (UPDATE … WHERE revoked_at IS NULL 的条件更新,未命中即已被轮换)。
|
|
144
|
+
*/
|
|
145
|
+
rotateRefreshToken(refreshToken: string, expectedClientId?: string): {
|
|
146
|
+
access_token: string;
|
|
147
|
+
refresh_token: string;
|
|
148
|
+
expires_in: number;
|
|
149
|
+
} | undefined;
|
|
150
|
+
/** RFC 7009 撤销(access 或 refresh;幂等,未知 token 也视为成功)。 */
|
|
151
|
+
revokeToken(token: string): void;
|
|
152
|
+
/**
|
|
153
|
+
* 签发一次性确认凭证(管理确认页渲染时按候选生成;绑定候选内容摘要 +
|
|
154
|
+
* 主体 + 商家 + 动作 + 10 分钟有效期)。返回明文 token(只进表单,不落库)。
|
|
155
|
+
*/
|
|
156
|
+
createConfirmation(input: {
|
|
157
|
+
candidateId: string;
|
|
158
|
+
candidateDigest: string;
|
|
159
|
+
principalId: string;
|
|
160
|
+
merchantId: string;
|
|
161
|
+
action: "approve" | "reject";
|
|
162
|
+
}): string;
|
|
163
|
+
/**
|
|
164
|
+
* 核销确认凭证(单次用途;逐项核对候选/摘要/主体/商家/动作,未过期未使用
|
|
165
|
+
* 才返回记录)。核对失败返回 undefined(fail-closed)。
|
|
166
|
+
*/
|
|
167
|
+
consumeConfirmation(token: string, expected: {
|
|
168
|
+
candidateId: string;
|
|
169
|
+
candidateDigest: string;
|
|
170
|
+
principalId: string;
|
|
171
|
+
merchantId: string;
|
|
172
|
+
action: "approve" | "reject";
|
|
173
|
+
}): {
|
|
174
|
+
candidate_id: string;
|
|
175
|
+
principal_id: string;
|
|
176
|
+
action: "approve" | "reject";
|
|
177
|
+
created_at: string;
|
|
178
|
+
} | undefined;
|
|
179
|
+
}
|
|
180
|
+
export interface MerchantOAuthServerOptions {
|
|
181
|
+
store: MerchantOAuthStore;
|
|
182
|
+
/** 本服务 base URL(https;loopback 开发可 http)。 */
|
|
183
|
+
issuer: string;
|
|
184
|
+
/** 被保护资源地址(MCP endpoint URL)。 */
|
|
185
|
+
resource: string;
|
|
186
|
+
/** 连接器 source(workbuddy 回调白名单用)。 */
|
|
187
|
+
connectorSource: string;
|
|
188
|
+
/** 单商家实例的展示名;通用网关省略时由已认证会话提供。 */
|
|
189
|
+
merchantName?: string;
|
|
190
|
+
/** 单商家实例归属商家;通用网关省略时由已认证会话决定。 */
|
|
191
|
+
merchantId?: string;
|
|
192
|
+
/** 只有通用网关才可开启:由经过验证的会话决定商家,不能意外省略 merchantId。 */
|
|
193
|
+
multiMerchant?: boolean;
|
|
194
|
+
/** 支持的 scope(缺省 merchant:read / merchant:write)。 */
|
|
195
|
+
scopes?: string[];
|
|
196
|
+
/** 回调策略(缺省按 connectorSource 派生 + 允许 loopback 回退)。 */
|
|
197
|
+
callbackPolicy?: OAuthCallbackPolicy;
|
|
198
|
+
/**
|
|
199
|
+
* 无会话时 authorize 的 303 落点(缺省单商家管理登录页 /admin/login)。
|
|
200
|
+
* 商家连接器入口传连接流程入口(如 /connect):它负责把商家送到目录登录/注册,
|
|
201
|
+
* 完成后带着会话回到同一 authorize 请求。
|
|
202
|
+
*/
|
|
203
|
+
loginPath?: string;
|
|
204
|
+
now?: () => string;
|
|
205
|
+
}
|
|
206
|
+
export declare class MerchantOAuthServer {
|
|
207
|
+
private readonly store;
|
|
208
|
+
private readonly issuer;
|
|
209
|
+
private readonly resource;
|
|
210
|
+
private readonly connectorSource;
|
|
211
|
+
private readonly merchantName;
|
|
212
|
+
private readonly merchantId;
|
|
213
|
+
private readonly scopes;
|
|
214
|
+
private readonly loginPath;
|
|
215
|
+
private readonly callbackPolicy;
|
|
216
|
+
constructor(options: MerchantOAuthServerOptions);
|
|
217
|
+
/** RFC 9728 resource metadata URL(401 WWW-Authenticate 指引用)。 */
|
|
218
|
+
get resourceMetadataUrl(): string;
|
|
219
|
+
/** RFC 9728 protected resource metadata。 */
|
|
220
|
+
protectedResourceMetadata(): OAuthHttpResult;
|
|
221
|
+
/** RFC 8414 authorization server metadata。 */
|
|
222
|
+
authorizationServerMetadata(): OAuthHttpResult;
|
|
223
|
+
/** RFC 7591 动态注册:只接受公共客户端(无 client_secret);回显 redirect_uris。 */
|
|
224
|
+
register(body: unknown): OAuthHttpResult;
|
|
225
|
+
/** GET /oauth/authorize:校验请求 → 授权确认页(CSRF 挂起单)。 */
|
|
226
|
+
/**
|
|
227
|
+
* GET /oauth/authorize:校验请求 → 授权确认页(CSRF 挂起单)。
|
|
228
|
+
* BUG-01:授权前必须持有有效管理登录会话——未登录 → 303 登录页(回跳
|
|
229
|
+
* 原授权 URL);会话商家 ≠ 本实例商家 → 拒绝(跨商家授权拒绝)。
|
|
230
|
+
* 挂起单绑定会话认证的 principal_id,授权码主体只能来自认证用户。
|
|
231
|
+
*/
|
|
232
|
+
authorize(query: Record<string, string | undefined>, session?: {
|
|
233
|
+
principal_id: string;
|
|
234
|
+
merchant_id: string;
|
|
235
|
+
merchant_name?: string;
|
|
236
|
+
}): OAuthHttpResult;
|
|
237
|
+
/**
|
|
238
|
+
* 授权流程在建立会话之前被中止(商家在目录拒绝了连接、连接失败)时的
|
|
239
|
+
* OAuth 2.1 错误回跳。
|
|
240
|
+
*
|
|
241
|
+
* 与 authorize 同一校验口径:client_id 与 redirect_uri 校验通过才回跳,
|
|
242
|
+
* 否则返回 400(防开放重定向)。客户端据此看到标准的 access_denied /
|
|
243
|
+
* server_error,而不是一个卡住的授权窗口。
|
|
244
|
+
*/
|
|
245
|
+
authorizationError(query: Record<string, string | undefined>, error: string, description: string): OAuthHttpResult;
|
|
246
|
+
/** POST /oauth/authorize(表单):会话 + CSRF 校验 → 授权码回跳 / access_denied。 */
|
|
247
|
+
authorizeSubmit(form: Record<string, string | undefined>, session: {
|
|
248
|
+
principal_id: string;
|
|
249
|
+
merchant_id: string;
|
|
250
|
+
}): OAuthHttpResult;
|
|
251
|
+
/** POST /oauth/token:authorization_code(PKCE 校验)/ refresh_token(轮换)。 */
|
|
252
|
+
token(form: Record<string, string | undefined>): OAuthHttpResult;
|
|
253
|
+
/** POST /oauth/revoke(RFC 7009;幂等,未知 token 也返回 200)。 */
|
|
254
|
+
revoke(form: Record<string, string | undefined>): OAuthHttpResult;
|
|
255
|
+
}
|