@svadmin/core 0.33.0 → 0.34.1
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/auth-hooks.svelte.ts +7 -4
- package/src/i18n.svelte.ts +2 -0
- package/src/permissions.svelte.ts +12 -16
- package/src/types.ts +5 -0
package/package.json
CHANGED
package/src/auth-hooks.svelte.ts
CHANGED
|
@@ -269,11 +269,14 @@ export function useOnError() {
|
|
|
269
269
|
// ─── usePermissions ──────────────────────────────────────────
|
|
270
270
|
|
|
271
271
|
/**
|
|
272
|
-
* Fetches
|
|
273
|
-
* Returns a reactive
|
|
274
|
-
*
|
|
272
|
+
* Fetches UI-only hints from authProvider.getPermissions().
|
|
273
|
+
* Returns a reactive UI helper with convenience methods for permission checks.
|
|
274
|
+
* The result can change labels, navigation, and disabled controls, but it runs
|
|
275
|
+
* in the browser and never authorizes API, RLS, or action requests. Those
|
|
276
|
+
* requests must be independently authenticated and authorized by the backend.
|
|
277
|
+
*
|
|
275
278
|
* Supports `refetch()` for session-level permission refresh (e.g., after role change).
|
|
276
|
-
*
|
|
279
|
+
*
|
|
277
280
|
* @example
|
|
278
281
|
* ```svelte
|
|
279
282
|
* <script>
|
package/src/i18n.svelte.ts
CHANGED
|
@@ -17,6 +17,7 @@ const baseLocales: Record<string, Record<string, string>> = {
|
|
|
17
17
|
'common.save': '保存',
|
|
18
18
|
'common.cancel': '取消',
|
|
19
19
|
'common.create': '新建',
|
|
20
|
+
'common.progress': '进度',
|
|
20
21
|
'common.edit': '编辑',
|
|
21
22
|
'common.delete': '删除',
|
|
22
23
|
'common.batchDeletePartialFail': '批量删除部分失败:{failed}/{total} 条未成功',
|
|
@@ -644,6 +645,7 @@ const baseLocales: Record<string, Record<string, string>> = {
|
|
|
644
645
|
'common.save': 'Save',
|
|
645
646
|
'common.cancel': 'Cancel',
|
|
646
647
|
'common.create': 'Create',
|
|
648
|
+
'common.progress': 'Progress',
|
|
647
649
|
'common.edit': 'Edit',
|
|
648
650
|
'common.delete': 'Delete',
|
|
649
651
|
'common.batchDeletePartialFail': 'Batch delete partially failed: {failed}/{total} unsuccessful',
|
|
@@ -20,8 +20,9 @@ export interface CanResult {
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* UI access-control integration point.
|
|
24
|
+
* It can mirror a backend policy decision for navigation and controls, but browser
|
|
25
|
+
* checks never authorize an API request. The backend must enforce the same policy.
|
|
25
26
|
*
|
|
26
27
|
* @example
|
|
27
28
|
* ```ts
|
|
@@ -78,8 +79,8 @@ export function getAccessControlOptions() {
|
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
82
|
+
* UI access check supporting single capabilities or a batch.
|
|
83
|
+
* Its result can change browser presentation but never authorizes the backend action.
|
|
83
84
|
*/
|
|
84
85
|
export async function canAccessAsync(params: CanParams[]): Promise<CanResult[]>;
|
|
85
86
|
export async function canAccessAsync(resource: string, action: Action, params?: Record<string, unknown>, meta?: Record<string, unknown>): Promise<CanResult>;
|
|
@@ -100,7 +101,7 @@ export async function canAccessAsync(resourceOrBatch: string | CanParams[], acti
|
|
|
100
101
|
// ─── Feature Gate ─────────────────────────────────────────────
|
|
101
102
|
|
|
102
103
|
export interface FeatureGateConfig {
|
|
103
|
-
/**
|
|
104
|
+
/** 仅用于前端展示的角色列表。 */
|
|
104
105
|
roles?: string[];
|
|
105
106
|
/**
|
|
106
107
|
* 需要的最低角色 (含以上所有角色)。
|
|
@@ -112,18 +113,20 @@ export interface FeatureGateConfig {
|
|
|
112
113
|
* 由调用方按自身业务定义,框架不预设任何角色。
|
|
113
114
|
*/
|
|
114
115
|
roleHierarchy?: string[];
|
|
115
|
-
/**
|
|
116
|
+
/** 仅用于前端展示的权限列表 (全部匹配)。 */
|
|
116
117
|
permissions?: string[];
|
|
117
118
|
}
|
|
118
119
|
|
|
120
|
+
/** 浏览器中的角色和权限提示,不是授权凭据。 */
|
|
119
121
|
export interface FeatureGateUser {
|
|
120
122
|
role: string;
|
|
121
123
|
permissions: string[];
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
+
* 创建仅用于前端展示的功能门控函数。
|
|
128
|
+
* 只做客户端 UI 门控;输入可被篡改,后端必须独立完成令牌验证和操作授权。
|
|
129
|
+
* 不预设任何角色层级,也不解释通配符权限。
|
|
127
130
|
*
|
|
128
131
|
* @example
|
|
129
132
|
* ```ts
|
|
@@ -157,14 +160,7 @@ export function createFeatureGate(config: FeatureGateConfig): (user: FeatureGate
|
|
|
157
160
|
}
|
|
158
161
|
|
|
159
162
|
if (config.permissions && config.permissions.length > 0) {
|
|
160
|
-
|
|
161
|
-
if (user.permissions.includes("*")) return true;
|
|
162
|
-
if (user.permissions.includes(permission)) return true;
|
|
163
|
-
const [resource] = permission.split(":");
|
|
164
|
-
if (resource && user.permissions.includes(`${resource}:*`)) return true;
|
|
165
|
-
return false;
|
|
166
|
-
});
|
|
167
|
-
if (!hasAll) return false;
|
|
163
|
+
if (!config.permissions.every((permission) => user.permissions.includes(permission))) return false;
|
|
168
164
|
}
|
|
169
165
|
|
|
170
166
|
return true;
|
package/src/types.ts
CHANGED
|
@@ -334,6 +334,11 @@ export interface AuthProvider {
|
|
|
334
334
|
logout: (params?: Record<string, unknown>) => Promise<AuthActionResult>;
|
|
335
335
|
check: (params?: Record<string, unknown>) => Promise<CheckResult>;
|
|
336
336
|
getIdentity: () => Promise<Identity | null>;
|
|
337
|
+
/**
|
|
338
|
+
* Returns UI-only permission hints for labels, navigation, or disabled controls.
|
|
339
|
+
* Browser-visible values are not authorization evidence: API, RLS, and action
|
|
340
|
+
* handlers must authenticate and authorize the request independently.
|
|
341
|
+
*/
|
|
337
342
|
getPermissions?: (params?: Record<string, unknown>) => Promise<unknown>;
|
|
338
343
|
register?: (params: Record<string, unknown>) => Promise<AuthActionResult>;
|
|
339
344
|
forgotPassword?: (params: Record<string, unknown>) => Promise<AuthActionResult>;
|