@autional-cn/shared 0.1.0-rc.5 → 0.1.0-rc.6
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/package.json +1 -1
- package/src/api/__tests__/namespace.test.ts +27 -0
- package/src/api/client.ts +7 -1
- package/src/api/namespace.ts +14 -0
- package/src/config/index.ts +4 -0
- package/src/vite-env.d.ts +1 -0
package/package.json
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { needsNamespaceHeader } from '../namespace';
|
|
3
|
+
|
|
4
|
+
describe('needsNamespaceHeader', () => {
|
|
5
|
+
it('密钥 admin 组端点(列表/子路径/查询)需注 X-Namespace', () => {
|
|
6
|
+
expect(needsNamespaceHeader('/secret/api/v1/admin/secrets')).toBe(true);
|
|
7
|
+
expect(needsNamespaceHeader('/secret/api/v1/admin/secrets/detail?key=a/b')).toBe(true);
|
|
8
|
+
expect(needsNamespaceHeader('/secret/api/v1/admin/secrets/batch-delete')).toBe(true);
|
|
9
|
+
expect(needsNamespaceHeader('/secret/api/v1/admin/secrets/policy')).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('非密钥 admin 端点不注头', () => {
|
|
13
|
+
expect(needsNamespaceHeader('/notification/api/v1/admin/announcements')).toBe(false);
|
|
14
|
+
expect(needsNamespaceHeader('/tenant/api/v1/admin/tenants')).toBe(false);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('secret 公开面/internal 面不注头(前端不消费)', () => {
|
|
18
|
+
expect(needsNamespaceHeader('/secret/public/jwt/public-key')).toBe(false);
|
|
19
|
+
expect(needsNamespaceHeader('/secret/api/v1/secret/public/transmission/public-key')).toBe(false);
|
|
20
|
+
expect(needsNamespaceHeader('/api/v1/internal/secret/jwt/keys')).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('相对路径缺省(undefined/空)不注头', () => {
|
|
24
|
+
expect(needsNamespaceHeader(undefined)).toBe(false);
|
|
25
|
+
expect(needsNamespaceHeader('')).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
});
|
package/src/api/client.ts
CHANGED
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
import axios, { AxiosError } from 'axios';
|
|
10
10
|
import type { AxiosInstance, InternalAxiosRequestConfig } from 'axios';
|
|
11
11
|
import { camelCaseKeys, snakeCaseKeys } from '../utils/case';
|
|
12
|
-
import { getApiBaseUrl } from '../config';
|
|
12
|
+
import { API_NAMESPACE, getApiBaseUrl } from '../config';
|
|
13
13
|
import { getTraceParentHeader } from './trace';
|
|
14
14
|
import { ENTRY_PLANE_HEADER, resolveEntryPlane } from './entry-plane';
|
|
15
|
+
import { NAMESPACE_HEADER, needsNamespaceHeader } from './namespace';
|
|
15
16
|
import { AuthService } from '../auth/service';
|
|
16
17
|
|
|
17
18
|
function setupInterceptors(instance: AxiosInstance) {
|
|
@@ -39,6 +40,11 @@ function setupInterceptors(instance: AxiosInstance) {
|
|
|
39
40
|
config.headers['X-Tenant-ID'] = tenantId;
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
// secret 管理面(§13-A P1-B):admin 组端点 fail-closed 要求 X-Namespace ∈ S
|
|
44
|
+
if (needsNamespaceHeader(config.url)) {
|
|
45
|
+
config.headers[NAMESPACE_HEADER] = API_NAMESPACE;
|
|
46
|
+
}
|
|
47
|
+
|
|
42
48
|
// 请求体 camelCase → snake_case 转换(后端 Go 期望 snake_case)
|
|
43
49
|
if (config.data && typeof config.data === 'object' && !(config.data instanceof FormData)) {
|
|
44
50
|
config.data = snakeCaseKeys(config.data);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* secret 服务管理面 namespace(§13-A P1-B / SEC-204/207):
|
|
3
|
+
* `/secret/api/v1/admin*` 端点 fail-closed 要求 `X-Namespace ∈ 实例服务集合 S`
|
|
4
|
+
* (NamespaceMiddleware,缺头/未服务 → 400)。值取部署配置 VITE_API_NAMESPACE
|
|
5
|
+
* (见 config,缺省 "dev" 与服务端 DefaultNamespace 对称)。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const NAMESPACE_HEADER = 'X-Namespace';
|
|
9
|
+
|
|
10
|
+
export const SECRET_ADMIN_PATH_PREFIX = '/secret/api/v1/admin';
|
|
11
|
+
|
|
12
|
+
export function needsNamespaceHeader(url?: string): boolean {
|
|
13
|
+
return !!url && url.includes(SECRET_ADMIN_PATH_PREFIX);
|
|
14
|
+
}
|
package/src/config/index.ts
CHANGED
|
@@ -356,6 +356,10 @@ export function getPLATFORM_CONSOLE_URL(): string {
|
|
|
356
356
|
}
|
|
357
357
|
export const API_BASE_URL = getEnv('VITE_API_BASE_URL', '/bff');
|
|
358
358
|
|
|
359
|
+
// secret 管理面 namespace(§13-A P1-B):admin 组端点要求 X-Namespace ∈ S(fail-closed);
|
|
360
|
+
// 缺省 "dev" 与服务端 DefaultNamespace(service-core cross/registry keyid.go)对称
|
|
361
|
+
export const API_NAMESPACE = getEnv('VITE_API_NAMESPACE', 'dev');
|
|
362
|
+
|
|
359
363
|
export function getApiBaseUrl(): string {
|
|
360
364
|
return API_BASE_URL;
|
|
361
365
|
}
|
package/src/vite-env.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ interface ImportMetaEnv {
|
|
|
9
9
|
readonly VITE_OAUTH_CLIENT_ID: string;
|
|
10
10
|
readonly VITE_AUTH_PAGES_URL: string;
|
|
11
11
|
readonly VITE_API_BASE_URL: string;
|
|
12
|
+
readonly VITE_API_NAMESPACE: string;
|
|
12
13
|
readonly VITE_AUDIT_BASE_URL: string;
|
|
13
14
|
[key: string]: string | boolean | undefined;
|
|
14
15
|
}
|