@downcity/city 0.2.205 → 0.2.213
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 +71 -5
- package/bin/client/bureau.d.ts +56 -0
- package/bin/client/bureau.d.ts.map +1 -0
- package/bin/client/bureau.js +253 -0
- package/bin/client/bureau.js.map +1 -0
- package/bin/client/city.d.ts +22 -79
- package/bin/client/city.d.ts.map +1 -1
- package/bin/client/city.js +51 -95
- package/bin/client/city.js.map +1 -1
- package/bin/client/types.d.ts +10 -70
- package/bin/client/types.d.ts.map +1 -1
- package/bin/client/types.js +3 -3
- package/bin/federation/auth/authenticator.d.ts +14 -13
- package/bin/federation/auth/authenticator.d.ts.map +1 -1
- package/bin/federation/auth/authenticator.js +33 -27
- package/bin/federation/auth/authenticator.js.map +1 -1
- package/bin/federation/auth/bureau-token-schema.d.ts +202 -0
- package/bin/federation/auth/bureau-token-schema.d.ts.map +1 -0
- package/bin/federation/auth/bureau-token-schema.js +35 -0
- package/bin/federation/auth/bureau-token-schema.js.map +1 -0
- package/bin/federation/auth/bureau-token-store.d.ts +22 -0
- package/bin/federation/auth/bureau-token-store.d.ts.map +1 -0
- package/bin/federation/auth/bureau-token-store.js +95 -0
- package/bin/federation/auth/bureau-token-store.js.map +1 -0
- package/bin/federation/auth/federation-key-store.d.ts +26 -0
- package/bin/federation/auth/federation-key-store.d.ts.map +1 -0
- package/bin/federation/auth/federation-key-store.js +96 -0
- package/bin/federation/auth/federation-key-store.js.map +1 -0
- package/bin/federation/auth/key-schema.d.ts +275 -0
- package/bin/federation/auth/key-schema.d.ts.map +1 -0
- package/bin/federation/auth/key-schema.js +44 -0
- package/bin/federation/auth/key-schema.js.map +1 -0
- package/bin/federation/auth/types.d.ts +62 -4
- package/bin/federation/auth/types.d.ts.map +1 -1
- package/bin/federation/auth/user-token-authority.d.ts +26 -0
- package/bin/federation/auth/user-token-authority.d.ts.map +1 -0
- package/bin/federation/auth/user-token-authority.js +179 -0
- package/bin/federation/auth/user-token-authority.js.map +1 -0
- package/bin/federation/federation-init.d.ts.map +1 -1
- package/bin/federation/federation-init.js +23 -4
- package/bin/federation/federation-init.js.map +1 -1
- package/bin/federation/federation-router.d.ts.map +1 -1
- package/bin/federation/federation-router.js +16 -0
- package/bin/federation/federation-router.js.map +1 -1
- package/bin/federation/federation-runtime.d.ts.map +1 -1
- package/bin/federation/federation-runtime.js +14 -2
- package/bin/federation/federation-runtime.js.map +1 -1
- package/bin/federation/federation.d.ts.map +1 -1
- package/bin/federation/federation.js +2 -0
- package/bin/federation/federation.js.map +1 -1
- package/bin/federation/runtime.d.ts +4 -0
- package/bin/federation/runtime.d.ts.map +1 -1
- package/bin/index.d.ts +6 -3
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +2 -1
- package/bin/index.js.map +1 -1
- package/bin/pact/admin/index.d.ts +7 -19
- package/bin/pact/admin/index.d.ts.map +1 -1
- package/bin/pact/admin/index.js +10 -18
- package/bin/pact/admin/index.js.map +1 -1
- package/bin/pact/admin/types.d.ts +4 -10
- package/bin/pact/admin/types.d.ts.map +1 -1
- package/bin/pact/invoker/bureaus/index.d.ts +25 -0
- package/bin/pact/invoker/bureaus/index.d.ts.map +1 -0
- package/bin/pact/invoker/bureaus/index.js +36 -0
- package/bin/pact/invoker/bureaus/index.js.map +1 -0
- package/bin/pact/invoker/cities/types.d.ts +2 -2
- package/bin/pact/invoker/cities/types.d.ts.map +1 -1
- package/bin/pact/invoker/user/index.d.ts +19 -0
- package/bin/pact/invoker/user/index.d.ts.map +1 -0
- package/bin/pact/invoker/user/index.js +24 -0
- package/bin/pact/invoker/user/index.js.map +1 -0
- package/bin/pact/user/index.d.ts +2 -1
- package/bin/pact/user/index.d.ts.map +1 -1
- package/bin/pact/user/index.js +7 -3
- package/bin/pact/user/index.js.map +1 -1
- package/bin/pact/user/types.d.ts +0 -2
- package/bin/pact/user/types.d.ts.map +1 -1
- package/bin/service/bureaus/bureaus-service.d.ts +13 -0
- package/bin/service/bureaus/bureaus-service.d.ts.map +1 -0
- package/bin/service/bureaus/bureaus-service.js +36 -0
- package/bin/service/bureaus/bureaus-service.js.map +1 -0
- package/bin/service/instruction.js +1 -1
- package/bin/service/instruction.js.map +1 -1
- package/bin/service/service.d.ts +3 -0
- package/bin/service/service.d.ts.map +1 -1
- package/bin/service/service.js +2 -0
- package/bin/service/service.js.map +1 -1
- package/bin/types/Bureau.d.ts +64 -0
- package/bin/types/Bureau.d.ts.map +1 -0
- package/bin/types/Bureau.js +8 -0
- package/bin/types/Bureau.js.map +1 -0
- package/bin/types/User.d.ts +24 -0
- package/bin/types/User.d.ts.map +1 -0
- package/bin/types/User.js +8 -0
- package/bin/types/User.js.map +1 -0
- package/package.json +4 -3
- package/bin/federation/auth/token-signer.d.ts +0 -27
- package/bin/federation/auth/token-signer.d.ts.map +0 -1
- package/bin/federation/auth/token-signer.js +0 -116
- package/bin/federation/auth/token-signer.js.map +0 -1
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* user_token 签发与校验模块。
|
|
3
|
-
*
|
|
4
|
-
* Downcity 使用 Web Crypto API 的 HMAC-SHA256 生成最小可用的 user_token。
|
|
5
|
-
* 零 Node.js 依赖,兼容所有现代运行时(Node、Workers、Deno、Bun、浏览器)。
|
|
6
|
-
*/
|
|
7
|
-
import { httpError, base64UrlEncode, base64UrlDecode, base64UrlEncodeBytes, base64UrlDecodeBytes, timingSafeEqualBytes } from "../../utils/helpers.js";
|
|
8
|
-
export class TokenSigner {
|
|
9
|
-
signingKey;
|
|
10
|
-
/** 缓存的 CryptoKey,避免每次签名都重新 import */
|
|
11
|
-
cryptoKey;
|
|
12
|
-
constructor(signingKey) {
|
|
13
|
-
if (!signingKey) {
|
|
14
|
-
throw new Error("TokenSigner requires a signing key");
|
|
15
|
-
}
|
|
16
|
-
this.signingKey = signingKey;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* 获取(或缓存)HMAC CryptoKey。
|
|
20
|
-
*
|
|
21
|
-
* 使用 Web Crypto API 的 crypto.subtle.importKey,
|
|
22
|
-
* 首次调用时创建并缓存 Promise,后续复用。
|
|
23
|
-
*/
|
|
24
|
-
getCryptoKey() {
|
|
25
|
-
if (!this.cryptoKey) {
|
|
26
|
-
const encoder = new TextEncoder();
|
|
27
|
-
this.cryptoKey = crypto.subtle.importKey("raw", encoder.encode(this.signingKey), { name: "HMAC", hash: "SHA-256" }, false, ["sign", "verify"]);
|
|
28
|
-
}
|
|
29
|
-
return this.cryptoKey;
|
|
30
|
-
}
|
|
31
|
-
/** 签发 user_token */
|
|
32
|
-
async sign(input) {
|
|
33
|
-
if (!input || typeof input.city_id !== "string" || input.city_id.length === 0) {
|
|
34
|
-
throw new TypeError("city_id is required");
|
|
35
|
-
}
|
|
36
|
-
if (typeof input.user_id !== "string" || input.user_id.length === 0) {
|
|
37
|
-
throw new TypeError("user_id is required");
|
|
38
|
-
}
|
|
39
|
-
const ttl = input.ttl;
|
|
40
|
-
const now = Math.floor(Date.now() / 1000);
|
|
41
|
-
const payload = {
|
|
42
|
-
aud: "downcity:user",
|
|
43
|
-
city_id: input.city_id,
|
|
44
|
-
user_id: input.user_id,
|
|
45
|
-
metadata: input.metadata ?? {},
|
|
46
|
-
iat: now,
|
|
47
|
-
};
|
|
48
|
-
if (ttl) {
|
|
49
|
-
payload.exp = now + TokenSigner.parseTTL(ttl);
|
|
50
|
-
}
|
|
51
|
-
const encodedPayload = base64UrlEncode(JSON.stringify(payload));
|
|
52
|
-
const signature = await signPayload(await this.getCryptoKey(), encodedPayload);
|
|
53
|
-
return `ub_${encodedPayload}.${signature}`;
|
|
54
|
-
}
|
|
55
|
-
/** 校验并解析 user_token,失败抛 httpError(401) */
|
|
56
|
-
async verify(token) {
|
|
57
|
-
const rawToken = token.startsWith("ub_") ? token.slice(3) : token;
|
|
58
|
-
const [encodedPayload, signature] = rawToken.split(".");
|
|
59
|
-
if (!encodedPayload || !signature) {
|
|
60
|
-
throw httpError(401, "Invalid user token");
|
|
61
|
-
}
|
|
62
|
-
if (!await verifyPayload(await this.getCryptoKey(), encodedPayload, signature)) {
|
|
63
|
-
throw httpError(401, "Invalid user token signature");
|
|
64
|
-
}
|
|
65
|
-
const payload = JSON.parse(base64UrlDecode(encodedPayload));
|
|
66
|
-
const now = Math.floor(Date.now() / 1000);
|
|
67
|
-
if (payload.exp && payload.exp <= now) {
|
|
68
|
-
throw httpError(401, "User token expired");
|
|
69
|
-
}
|
|
70
|
-
if (payload.aud !== "downcity:user") {
|
|
71
|
-
throw httpError(401, "Invalid user token audience");
|
|
72
|
-
}
|
|
73
|
-
if (!payload.city_id || !payload.user_id) {
|
|
74
|
-
throw httpError(401, "Invalid user token payload");
|
|
75
|
-
}
|
|
76
|
-
return payload;
|
|
77
|
-
}
|
|
78
|
-
/** 把 ttl 解析成秒数 */
|
|
79
|
-
static parseTTL(ttl) {
|
|
80
|
-
if (typeof ttl === "number" && Number.isFinite(ttl) && ttl > 0) {
|
|
81
|
-
return ttl;
|
|
82
|
-
}
|
|
83
|
-
if (typeof ttl !== "string") {
|
|
84
|
-
throw new TypeError("ttl must be a positive number of seconds or a string like 1h");
|
|
85
|
-
}
|
|
86
|
-
const match = ttl.match(/^(\d+)(s|m|h|d)$/);
|
|
87
|
-
if (!match) {
|
|
88
|
-
throw new Error(`Invalid ttl: ${ttl}`);
|
|
89
|
-
}
|
|
90
|
-
const value = Number(match[1]);
|
|
91
|
-
const unit = match[2];
|
|
92
|
-
const multipliers = {
|
|
93
|
-
s: 1,
|
|
94
|
-
m: 60,
|
|
95
|
-
h: 60 * 60,
|
|
96
|
-
d: 24 * 60 * 60,
|
|
97
|
-
};
|
|
98
|
-
return value * multipliers[unit];
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* 使用 HMAC-SHA256 对 payload 签名,返回 base64url 编码的签名。
|
|
103
|
-
*/
|
|
104
|
-
async function signPayload(cryptoKey, encodedPayload) {
|
|
105
|
-
const signature = await crypto.subtle.sign("HMAC", cryptoKey, new TextEncoder().encode(encodedPayload));
|
|
106
|
-
return base64UrlEncodeBytes(new Uint8Array(signature));
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* 验证 HMAC-SHA256 签名是否匹配。
|
|
110
|
-
*/
|
|
111
|
-
async function verifyPayload(cryptoKey, encodedPayload, signature) {
|
|
112
|
-
const expected = base64UrlDecodeBytes(signature);
|
|
113
|
-
const actual = await crypto.subtle.sign("HMAC", cryptoKey, new TextEncoder().encode(encodedPayload));
|
|
114
|
-
return timingSafeEqualBytes(new Uint8Array(actual), expected);
|
|
115
|
-
}
|
|
116
|
-
//# sourceMappingURL=token-signer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"token-signer.js","sourceRoot":"","sources":["../../../src/federation/auth/token-signer.ts"],"names":[],"mappings":"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"}
|