cabloy 5.1.104 → 5.1.105
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/.cabloy-version +1 -1
- package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +1 -1
- package/CHANGELOG.md +9 -0
- package/CLAUDE.md +1 -0
- package/cabloy-docs/backend/controller-aop-guide.md +2 -2
- package/cabloy-docs/backend/field-indexes.md +10 -1
- package/cabloy-docs/backend/menu-guide.md +30 -0
- package/cabloy-docs/frontend/model-state-guide.md +2 -0
- package/cabloy-docs/frontend/use-state-data-best-practices.md +23 -0
- package/package.json +1 -1
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/pnpm-lock.yaml +27 -27
- package/vona/src/suite/a-home/modules/home-user/src/bean/eventListener.activate.ts +5 -4
- package/vona/src/suite/a-home/modules/home-user/src/bean/meta.version.ts +10 -6
- package/vona/src/suite/a-home/modules/home-user/src/config/config.ts +1 -1
- package/vona/src/suite/a-home/modules/home-user/src/entity/role.ts +4 -0
- package/vona/src/suite/a-home/modules/home-user/src/service/passportAdapter.ts +2 -2
- package/vona/src/suite/a-home/modules/home-user/src/service/roleAdapter.ts +5 -5
- package/vona/src/suite/a-training/modules/training-record/src/bean/ssrMenu.record.ts +1 -0
- package/vona/src/suite/a-training/modules/training-student/src/bean/ssrMenu.student.ts +1 -0
- package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/bean/ssrMenu.home.ts +1 -0
- package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/bean/ssrSite.admin.ts +5 -1
- package/vona/src/suite/cabloy-basic/modules/basic-siteweb/src/bean/ssrSite.web.ts +5 -1
- package/vona/src/suite-vendor/a-auth/modules/a-auth/package.json +1 -1
- package/vona/src/suite-vendor/a-auth/modules/a-auth/src/service/auth.ts +5 -1
- package/vona/src/suite-vendor/a-auth/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/cli/ssrSite/boilerplate/{{sceneName}}.{{beanName}}.ts_ +5 -3
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/bean/event.retrieveMenusSite.ts +2 -2
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/lib/beanSsrSiteBase.ts +33 -8
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/service/ssr.ts +46 -16
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/service/ssrHandler.ts +2 -4
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/env.ts +1 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/ssrMenu.ts +10 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/ssrSite.ts +3 -1
- package/vona/src/suite-vendor/a-cabloy/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/src/.metadata/index.ts +18 -2
- package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +6 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/event.retrievePermissionAction.ts +16 -0
- package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-user/src/bean/bean.passport.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-user/src/lib/passport.ts +7 -4
- package/vona/src/suite-vendor/a-vona/modules/a-user/src/types/passport.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-user/src/types/role.ts +3 -1
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/env/.env.cabloyBasicAdmin +2 -0
- package/zova/env/.env.cabloyBasicWeb +2 -0
- package/zova/packages-utils/zova-jsx/package.json +2 -2
- package/zova/packages-zova/zova/package.json +3 -3
- package/zova/packages-zova/zova-core/package.json +1 -1
- package/zova/packages-zova/zova-core/src/core/sys/sys.ts +3 -0
- package/zova/packages-zova/zova-core/src/types/utils/env.ts +1 -0
- package/zova/src/suite/a-home/modules/home-api/src/api/homeUserPassport.ts +19 -19
- package/zova/src/suite/a-home/modules/home-api/src/api/openapi/types.ts +11 -10
- package/zova/src/suite/a-home/modules/home-api/src/apiSchema/homeUserPassport.ts +5 -5
- package/zova/src/suite/a-home/modules/home-base/src/.metadata/page/errorAccessDenied.ts +9 -0
- package/zova/src/suite/a-home/modules/home-base/src/page/errorAccessDenied/controller.tsx +40 -0
- package/zova/src/suite/a-home/modules/home-base/src/routes.ts +9 -0
- package/zova/src/suite/a-home/modules/home-base/src/service/routerGuards.ts +21 -12
- package/zova/src/suite/a-home/modules/home-passport/src/model/passport.ts +2 -2
- package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/monkeySys.ts +10 -1
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/router.ts +1 -0
- package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/package.json +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ZovaMetaMode } from '@cabloy/module-info';
|
|
2
2
|
import type { IParamsAndQuery } from '@cabloy/utils';
|
|
3
3
|
import type { ILocaleRecord } from 'vona';
|
|
4
|
-
import type { IMenuGroup
|
|
4
|
+
import type { IMenuGroup } from 'vona-module-a-menu';
|
|
5
5
|
import type { IOnionSlice } from 'vona-module-a-onion';
|
|
6
6
|
import type { TypeEventResolvePathData, TypeEventResolvePathResult } from 'vona-module-a-static';
|
|
7
7
|
|
|
@@ -16,7 +16,12 @@ import { BeanBase, cast, deepExtend, SymbolModuleName } from 'vona';
|
|
|
16
16
|
import { checkErrorJwtExpiredAndThrow } from 'vona-module-a-jwt';
|
|
17
17
|
|
|
18
18
|
import type { TypeEventRetrieveMenusResult } from '../bean/event.retrieveMenus.ts';
|
|
19
|
-
import type {
|
|
19
|
+
import type { TypeEventRetrieveMenusSiteResult } from '../bean/event.retrieveMenusSite.ts';
|
|
20
|
+
import type {
|
|
21
|
+
IDecoratorSsrMenuOptions,
|
|
22
|
+
ISsrMenuItemPrepared,
|
|
23
|
+
ISsrMenuRecord,
|
|
24
|
+
} from '../types/ssrMenu.ts';
|
|
20
25
|
import type { ISsrMenuGroupRecord } from '../types/ssrMenuGroup.ts';
|
|
21
26
|
import type {
|
|
22
27
|
IDecoratorSsrSiteOptions,
|
|
@@ -139,7 +144,15 @@ export class BeanSsrSiteBase<
|
|
|
139
144
|
}
|
|
140
145
|
|
|
141
146
|
async retrieveMenus(): Promise<TypeEventRetrieveMenusResult | undefined> {
|
|
142
|
-
|
|
147
|
+
const menusPrepared = await this._getMenusCache(this.ctx.locale);
|
|
148
|
+
if (!menusPrepared) return;
|
|
149
|
+
const menus = menusPrepared.menus
|
|
150
|
+
?.filter(menu => !menu.roles?.length || this.bean.passport.checkRoleName(menu.roles))
|
|
151
|
+
.map(menu => {
|
|
152
|
+
const { roles: _roles, ...menuPublic } = menu;
|
|
153
|
+
return menuPublic;
|
|
154
|
+
});
|
|
155
|
+
return { menus, groups: menusPrepared.groups };
|
|
143
156
|
}
|
|
144
157
|
|
|
145
158
|
public get siteOptions() {
|
|
@@ -168,6 +181,14 @@ export class BeanSsrSiteBase<
|
|
|
168
181
|
},
|
|
169
182
|
this.$scope.ssr.config.site.default,
|
|
170
183
|
onionOptions,
|
|
184
|
+
{
|
|
185
|
+
envServer: {
|
|
186
|
+
SITE_ID: onionOptions.siteId,
|
|
187
|
+
},
|
|
188
|
+
envClient: {
|
|
189
|
+
SITE_ID: onionOptions.siteId,
|
|
190
|
+
},
|
|
191
|
+
},
|
|
171
192
|
);
|
|
172
193
|
}
|
|
173
194
|
return this._siteOptions;
|
|
@@ -253,9 +274,11 @@ export class BeanSsrSiteBase<
|
|
|
253
274
|
};
|
|
254
275
|
}
|
|
255
276
|
|
|
256
|
-
private async _getMenusCache(
|
|
277
|
+
private async _getMenusCache(
|
|
278
|
+
locale: keyof ILocaleRecord,
|
|
279
|
+
): Promise<TypeEventRetrieveMenusSiteResult | undefined> {
|
|
257
280
|
if (!this.app.meta[SymbolCacheMenus]) this.app.meta[SymbolCacheMenus] = {};
|
|
258
|
-
const cacheMenus: Record<keyof ILocaleRecord,
|
|
281
|
+
const cacheMenus: Record<keyof ILocaleRecord, TypeEventRetrieveMenusSiteResult> =
|
|
259
282
|
this.app.meta[SymbolCacheMenus];
|
|
260
283
|
const beanFullName = this.$beanFullName;
|
|
261
284
|
const instanceName = this.ctx.instanceName;
|
|
@@ -268,7 +291,9 @@ export class BeanSsrSiteBase<
|
|
|
268
291
|
return cacheMenus[beanFullName][cacheKey];
|
|
269
292
|
}
|
|
270
293
|
|
|
271
|
-
private async _prepareMenus(
|
|
294
|
+
private async _prepareMenus(
|
|
295
|
+
locale: keyof ILocaleRecord,
|
|
296
|
+
): Promise<TypeEventRetrieveMenusSiteResult | undefined> {
|
|
272
297
|
return await this.$scope.ssr.event.retrieveMenusSite.emit(
|
|
273
298
|
{ ssrSite: this, locale },
|
|
274
299
|
async () => {
|
|
@@ -287,7 +312,7 @@ export class BeanSsrSiteBase<
|
|
|
287
312
|
private _prepareMenusOrGroups<T extends keyof ISsrMenuRecord>(
|
|
288
313
|
locale: keyof ILocaleRecord,
|
|
289
314
|
ssrMenus: IOnionSlice<ISsrMenuRecord, T, unknown>[],
|
|
290
|
-
):
|
|
315
|
+
): ISsrMenuItemPrepared[];
|
|
291
316
|
private _prepareMenusOrGroups<T extends keyof ISsrMenuGroupRecord>(
|
|
292
317
|
locale: keyof ILocaleRecord,
|
|
293
318
|
ssrMenus: IOnionSlice<ISsrMenuGroupRecord, T, unknown>[],
|
|
@@ -298,7 +323,7 @@ export class BeanSsrSiteBase<
|
|
|
298
323
|
) {
|
|
299
324
|
const siteOnionName = this.$onionName;
|
|
300
325
|
// menus
|
|
301
|
-
const menus:
|
|
326
|
+
const menus: ISsrMenuItemPrepared[] = [];
|
|
302
327
|
for (const ssrMenu of ssrMenus) {
|
|
303
328
|
const siteMenuOptions = ssrMenu.beanOptions
|
|
304
329
|
.options as IDecoratorSsrMenuOptions<IDecoratorSsrSiteOptions>;
|
|
@@ -16,22 +16,52 @@ export class ServiceSsr extends BeanBase {
|
|
|
16
16
|
if (!this.app.meta[SymbolCacheSites]) this.app.meta[SymbolCacheSites] = {};
|
|
17
17
|
if (!this.app.meta[SymbolCacheSites][cacheKey]) {
|
|
18
18
|
// check sites
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
19
|
+
const sites = this.bean.onion.ssrSite.getOnionsEnabled(this.ctx.instanceName!).toReversed();
|
|
20
|
+
const siteIds = new Map<string, string>();
|
|
21
|
+
const publicPaths = new Map<string, string>();
|
|
22
|
+
for (const site of sites) {
|
|
23
|
+
const siteOptions = site.beanOptions.options as IDecoratorSsrSiteOptions;
|
|
24
|
+
const beanFullName = site.beanOptions.beanFullName;
|
|
25
|
+
const siteId = siteOptions.siteId;
|
|
26
|
+
if (typeof siteId !== 'string' || !siteId.trim()) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
`Should specify non-empty siteId for SSR site: ${beanFullName} (${cacheKey})`,
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
const siteIdDuplicate = siteIds.get(siteId);
|
|
32
|
+
if (siteIdDuplicate) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Duplicate SSR siteId "${siteId}" for ${siteIdDuplicate} and ${beanFullName} (${cacheKey})`,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
siteIds.set(siteId, beanFullName);
|
|
38
|
+
const publicPath = siteOptions.publicPath;
|
|
39
|
+
if (typeof publicPath !== 'string') {
|
|
40
|
+
throw new TypeError(
|
|
41
|
+
`Should specify publicPath for SSR site: ${beanFullName} (${cacheKey})`,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
const publicPathDuplicate = publicPaths.get(publicPath);
|
|
45
|
+
if (publicPathDuplicate) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
`Duplicate SSR publicPath "${publicPath}" for ${publicPathDuplicate} and ${beanFullName} (${cacheKey})`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
publicPaths.set(publicPath, beanFullName);
|
|
51
|
+
}
|
|
52
|
+
this.app.meta[SymbolCacheSites][cacheKey] = sites.sort((site1, site2) => {
|
|
53
|
+
const siteOptions1 = site1.beanOptions.options as IDecoratorSsrSiteOptions;
|
|
54
|
+
const siteOptions2 = site2.beanOptions.options as IDecoratorSsrSiteOptions;
|
|
55
|
+
const publicPath1 = `/${siteOptions1.publicPath}`;
|
|
56
|
+
const publicPath2 = `/${siteOptions2.publicPath}`;
|
|
57
|
+
return publicPath1 === publicPath2
|
|
58
|
+
? 0
|
|
59
|
+
: publicPath1.startsWith(publicPath2)
|
|
60
|
+
? -1
|
|
61
|
+
: publicPath2.startsWith(publicPath1)
|
|
62
|
+
? 1
|
|
63
|
+
: 0;
|
|
64
|
+
});
|
|
35
65
|
}
|
|
36
66
|
return this.app.meta[SymbolCacheSites][cacheKey];
|
|
37
67
|
}
|
|
@@ -68,10 +68,8 @@ export class ServiceSsrHandler extends BeanBase {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
private _createMissingBundleMessage() {
|
|
71
|
-
const
|
|
72
|
-
const siteName = diagnostics?.siteName ?? String(this._siteOptions.publicPath || 'unknown');
|
|
73
|
-
const buildCommand = diagnostics?.buildCommand;
|
|
71
|
+
const buildCommand = this._siteOptions.diagnostics?.buildCommand;
|
|
74
72
|
const commandHint = buildCommand ? ` Run "${buildCommand}" at the repository root.` : '';
|
|
75
|
-
return `Missing SSR bundle for site ${
|
|
73
|
+
return `Missing SSR bundle for site ${this._siteOptions.siteId}: ${this._siteAssetDir}.${commandHint}`;
|
|
76
74
|
}
|
|
77
75
|
}
|
|
@@ -4,6 +4,7 @@ export interface ZovaConfigEnv {
|
|
|
4
4
|
META_FLAVOR: ZovaMetaFlavor;
|
|
5
5
|
META_MODE: ZovaMetaMode;
|
|
6
6
|
META_APP_MODE: ZovaMetaAppMode;
|
|
7
|
+
SITE_ID: string;
|
|
7
8
|
APP_ROUTER_MODE: 'hash' | 'history' | 'abstract' | undefined;
|
|
8
9
|
APP_ROUTER_BASE: string | undefined;
|
|
9
10
|
APP_PUBLIC_PATH: string | undefined;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ILocaleRecord, OmitNever } from 'vona';
|
|
2
|
-
import type { IMenuItem } from 'vona-module-a-menu';
|
|
2
|
+
import type { IMenuGroup, IMenuItem } from 'vona-module-a-menu';
|
|
3
3
|
import type { IOnionOptionsEnable, ServiceOnion } from 'vona-module-a-onion';
|
|
4
|
+
import type { IRoleNameRecord } from 'vona-module-a-user';
|
|
4
5
|
|
|
5
6
|
import type { ISsrMenuGroupRecord } from './ssrMenuGroup.ts';
|
|
6
7
|
import type { IDecoratorSsrSiteOptions, ISsrSiteRecord } from './ssrSite.ts';
|
|
@@ -12,6 +13,14 @@ export interface ISsrMenuItem<Pages extends {} = {}, Icons extends {} = {}> exte
|
|
|
12
13
|
'name' | 'group'
|
|
13
14
|
> {
|
|
14
15
|
group?: keyof ISsrMenuGroupRecord | (keyof ISsrMenuGroupRecord)[];
|
|
16
|
+
roles?: (keyof IRoleNameRecord)[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type ISsrMenuItemPrepared = IMenuItem<any, any> & Pick<ISsrMenuItem<any, any>, 'roles'>;
|
|
20
|
+
|
|
21
|
+
export interface ISsrMenusPrepared {
|
|
22
|
+
menus?: ISsrMenuItemPrepared[];
|
|
23
|
+
groups?: IMenuGroup[];
|
|
15
24
|
}
|
|
16
25
|
|
|
17
26
|
// should not set default generic = IDecoratorSsrSiteOptions
|
|
@@ -46,12 +46,13 @@ export interface SSRContextState {
|
|
|
46
46
|
pageData?: unknown;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
export interface ISsrSiteIdRecord {}
|
|
50
|
+
|
|
49
51
|
export interface ISsrSitePublicPathRecord {}
|
|
50
52
|
|
|
51
53
|
export interface ISsrSiteRecord {}
|
|
52
54
|
|
|
53
55
|
export interface ISsrSiteDiagnosticsOptions {
|
|
54
|
-
siteName?: string;
|
|
55
56
|
buildCommand?: string;
|
|
56
57
|
}
|
|
57
58
|
|
|
@@ -68,6 +69,7 @@ export interface IDecoratorSsrSiteOptions<
|
|
|
68
69
|
extends
|
|
69
70
|
IOnionOptionsEnable,
|
|
70
71
|
IOnionOptionsMatch<TypeOnionOptionsMatchRule<keyof IInstanceRecord>> {
|
|
72
|
+
siteId: keyof ISsrSiteIdRecord;
|
|
71
73
|
publicPath: keyof ISsrSitePublicPathRecord;
|
|
72
74
|
bundlePath: string;
|
|
73
75
|
diagnostics?: ISsrSiteDiagnosticsOptions;
|
|
@@ -27,6 +27,7 @@ declare module 'vona' {
|
|
|
27
27
|
}
|
|
28
28
|
/** bean: end */
|
|
29
29
|
/** event: begin */
|
|
30
|
+
export * from '../bean/event.retrievePermissionAction.ts';
|
|
30
31
|
export * from '../bean/event.retrievePermissions.ts';
|
|
31
32
|
|
|
32
33
|
import 'vona';
|
|
@@ -36,6 +37,17 @@ declare module 'vona' {
|
|
|
36
37
|
}
|
|
37
38
|
declare module 'vona-module-a-permission' {
|
|
38
39
|
|
|
40
|
+
export interface EventRetrievePermissionAction {
|
|
41
|
+
/** @internal */
|
|
42
|
+
get scope(): ScopeModuleAPermission;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface EventRetrievePermissionAction {
|
|
46
|
+
get $beanFullName(): 'a-permission.event.retrievePermissionAction';
|
|
47
|
+
get $onionName(): 'a-permission:retrievePermissionAction';
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
39
51
|
export interface EventRetrievePermissions {
|
|
40
52
|
/** @internal */
|
|
41
53
|
get scope(): ScopeModuleAPermission;
|
|
@@ -49,17 +61,21 @@ declare module 'vona-module-a-permission' {
|
|
|
49
61
|
}
|
|
50
62
|
/** event: end */
|
|
51
63
|
/** event: begin */
|
|
64
|
+
import type { EventRetrievePermissionAction } from '../bean/event.retrievePermissionAction.ts';
|
|
52
65
|
import type { EventRetrievePermissions } from '../bean/event.retrievePermissions.ts';
|
|
53
66
|
export interface IModuleEvent {
|
|
54
|
-
'
|
|
67
|
+
'retrievePermissionAction': EventRetrievePermissionAction;
|
|
68
|
+
'retrievePermissions': EventRetrievePermissions;
|
|
55
69
|
}
|
|
56
70
|
/** event: end */
|
|
57
71
|
/** event: begin */
|
|
72
|
+
import type { TypeEventRetrievePermissionActionData, TypeEventRetrievePermissionActionResult } from '../bean/event.retrievePermissionAction.ts';
|
|
58
73
|
import type { TypeEventRetrievePermissionsData, TypeEventRetrievePermissionsResult } from '../bean/event.retrievePermissions.ts';
|
|
59
74
|
import type { EventOn } from 'vona-module-a-event';
|
|
60
75
|
declare module 'vona-module-a-event' {
|
|
61
76
|
export interface IEventRecord {
|
|
62
|
-
'a-permission:
|
|
77
|
+
'a-permission:retrievePermissionAction': EventOn<TypeEventRetrievePermissionActionData, TypeEventRetrievePermissionActionResult>;
|
|
78
|
+
'a-permission:retrievePermissions': EventOn<TypeEventRetrievePermissionsData, TypeEventRetrievePermissionsResult>;
|
|
63
79
|
}
|
|
64
80
|
}
|
|
65
81
|
/** event: end */
|
|
@@ -88,7 +88,12 @@ export class BeanPermission extends BeanBase {
|
|
|
88
88
|
const route = this._getControllerActionRoute(resource, actionKey);
|
|
89
89
|
if (!route?.route?.meta) return false;
|
|
90
90
|
if (!this._matchPassportMeta(route.route.meta)) return false;
|
|
91
|
-
return await this.
|
|
91
|
+
return await this.scope.event.retrievePermissionAction.emit(
|
|
92
|
+
{ resource, actionKey },
|
|
93
|
+
async () => {
|
|
94
|
+
return await this.retrievePermissionActionByRoles(resource, actionKey);
|
|
95
|
+
},
|
|
96
|
+
);
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
@Caching.get({
|
package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/event.retrievePermissionAction.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IResourceRecord } from 'vona-module-a-openapi';
|
|
2
|
+
|
|
3
|
+
import { BeanEventBase, Event } from 'vona-module-a-event';
|
|
4
|
+
|
|
5
|
+
export interface TypeEventRetrievePermissionActionData {
|
|
6
|
+
resource: keyof IResourceRecord;
|
|
7
|
+
actionKey: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type TypeEventRetrievePermissionActionResult = boolean;
|
|
11
|
+
|
|
12
|
+
@Event()
|
|
13
|
+
export class EventRetrievePermissionAction extends BeanEventBase<
|
|
14
|
+
TypeEventRetrievePermissionActionData,
|
|
15
|
+
TypeEventRetrievePermissionActionResult
|
|
16
|
+
> {}
|
|
@@ -53,9 +53,9 @@ export class BeanPassport extends BeanBase {
|
|
|
53
53
|
return !!user && !!user.activated;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
public async
|
|
56
|
+
public async isSystemAdmin(): Promise<boolean> {
|
|
57
57
|
const passport = this.current;
|
|
58
|
-
return await this.passportAdapter.
|
|
58
|
+
return await this.passportAdapter.isSystemAdmin(passport);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
public async setCurrent(passport: IPassport | undefined) {
|
|
@@ -15,22 +15,25 @@ function RoleName(options?: Partial<IGuardOptionsRoleName>): ClassDecorator & Me
|
|
|
15
15
|
return Aspect.guard('a-user:roleName', options);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
function
|
|
18
|
+
function SystemAdmin(
|
|
19
19
|
options?: Partial<Omit<IGuardOptionsRoleName, 'name'>>,
|
|
20
20
|
): ClassDecorator & MethodDecorator {
|
|
21
|
-
return Aspect.guard(
|
|
21
|
+
return Aspect.guard(
|
|
22
|
+
'a-user:roleName',
|
|
23
|
+
Object.assign({}, options, { name: 'systemAdmin' as const }),
|
|
24
|
+
);
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
export interface IDecoratorGroupPassport {
|
|
25
28
|
public: typeof Public;
|
|
26
29
|
activated: typeof Activated;
|
|
27
30
|
roleName: typeof RoleName;
|
|
28
|
-
|
|
31
|
+
systemAdmin: typeof SystemAdmin;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
export const Passport: IDecoratorGroupPassport = {
|
|
32
35
|
public: Public,
|
|
33
36
|
activated: Activated,
|
|
34
37
|
roleName: RoleName,
|
|
35
|
-
|
|
38
|
+
systemAdmin: SystemAdmin,
|
|
36
39
|
} as unknown as IDecoratorGroupPassport;
|
|
@@ -11,7 +11,7 @@ export interface IPassport {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export interface IPassportAdapter {
|
|
14
|
-
|
|
14
|
+
isSystemAdmin(passport: IPassport | undefined): Promise<boolean>;
|
|
15
15
|
setCurrent(passport: IPassport | undefined): Promise<IPassport | undefined>;
|
|
16
16
|
serialize(passport: IPassport): Promise<IPayloadData>;
|
|
17
17
|
deserialize(payloadData: IPayloadData): Promise<IPassport | undefined>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { TableIdentity } from 'table-identity';
|
|
2
2
|
|
|
3
3
|
export interface IRoleNameRecord {
|
|
4
|
-
|
|
4
|
+
registeredUser: never;
|
|
5
|
+
systemAdmin: never;
|
|
5
6
|
}
|
|
6
7
|
|
|
7
8
|
export interface IRoleIdRecord {}
|
|
@@ -9,6 +10,7 @@ export interface IRoleIdRecord {}
|
|
|
9
10
|
export interface IRole {
|
|
10
11
|
id: TableIdentity;
|
|
11
12
|
name: string;
|
|
13
|
+
siteIds: string[];
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export interface IRoleAdapter {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zova-jsx",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.78",
|
|
4
4
|
"gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
|
|
5
5
|
"description": "Zova JSX",
|
|
6
6
|
"keywords": [
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@cabloy/word-utils": "^2.1.14",
|
|
51
51
|
"typestyle": "^2.4.0",
|
|
52
52
|
"vue": "^3.5.38",
|
|
53
|
-
"zova-core": "^5.1.
|
|
53
|
+
"zova-core": "^5.1.78"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"clean-package": "^2.2.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zova",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.135",
|
|
4
4
|
"gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
|
|
5
5
|
"description": "A vue3 framework with ioc",
|
|
6
6
|
"keywords": [
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"postpack": "clean-package restore"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"zova-core": "^5.1.
|
|
49
|
-
"zova-suite-a-zova": "^5.1.
|
|
48
|
+
"zova-core": "^5.1.78",
|
|
49
|
+
"zova-suite-a-zova": "^5.1.134"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"clean-package": "^2.2.0",
|
|
@@ -132,6 +132,9 @@ export class ZovaSys {
|
|
|
132
132
|
private _prepareEnv(env: NodeJS.ProcessEnv, envRuntime?: Partial<ZovaConfigEnv>): ZovaConfigEnv {
|
|
133
133
|
const env2 = this._prepareEnv_Runtime(env, envRuntime);
|
|
134
134
|
const env3 = this._prepareEnv_Client(env2 as any);
|
|
135
|
+
if (!env3.SITE_ID?.trim()) {
|
|
136
|
+
throw new Error(`Should specify SITE_ID for Zova flavor: ${env3.META_FLAVOR}`);
|
|
137
|
+
}
|
|
135
138
|
return env3;
|
|
136
139
|
}
|
|
137
140
|
|
|
@@ -76,6 +76,17 @@ export type ApiApiHomeUserPassportmigrateRequestQuery =
|
|
|
76
76
|
export type ApiApiHomeUserPassportmigrateResponseBody =
|
|
77
77
|
paths[ApiApiHomeUserPassportmigratePath][ApiApiHomeUserPassportmigrateMethod]['responses']['200']['content']['application/json']['data'];
|
|
78
78
|
|
|
79
|
+
/** HomeUserPassport_refreshAuthToken */
|
|
80
|
+
export const ApiApiHomeUserPassportrefreshAuthTokenPath =
|
|
81
|
+
'/api/home/user/passport/refreshAuthToken';
|
|
82
|
+
export type ApiApiHomeUserPassportrefreshAuthTokenPath = '/api/home/user/passport/refreshAuthToken';
|
|
83
|
+
export type ApiApiHomeUserPassportrefreshAuthTokenMethod = 'post';
|
|
84
|
+
export type ApiApiHomeUserPassportrefreshAuthTokenRequestBody = {
|
|
85
|
+
refreshToken: string;
|
|
86
|
+
};
|
|
87
|
+
export type ApiApiHomeUserPassportrefreshAuthTokenResponseBody =
|
|
88
|
+
paths[ApiApiHomeUserPassportrefreshAuthTokenPath][ApiApiHomeUserPassportrefreshAuthTokenMethod]['responses']['200']['content']['application/json']['data'];
|
|
89
|
+
|
|
79
90
|
/** HomeUserPassport_createPassportJwtFromOauthCode */
|
|
80
91
|
export const ApiApiHomeUserPassportcreatePassportJwtFromOauthCodePath =
|
|
81
92
|
'/api/home/user/passport/createPassportJwtFromOauthCode';
|
|
@@ -88,17 +99,6 @@ export type ApiApiHomeUserPassportcreatePassportJwtFromOauthCodeRequestBody = {
|
|
|
88
99
|
export type ApiApiHomeUserPassportcreatePassportJwtFromOauthCodeResponseBody =
|
|
89
100
|
paths[ApiApiHomeUserPassportcreatePassportJwtFromOauthCodePath][ApiApiHomeUserPassportcreatePassportJwtFromOauthCodeMethod]['responses']['200']['content']['application/json']['data'];
|
|
90
101
|
|
|
91
|
-
/** HomeUserPassport_refreshAuthToken */
|
|
92
|
-
export const ApiApiHomeUserPassportrefreshAuthTokenPath =
|
|
93
|
-
'/api/home/user/passport/refreshAuthToken';
|
|
94
|
-
export type ApiApiHomeUserPassportrefreshAuthTokenPath = '/api/home/user/passport/refreshAuthToken';
|
|
95
|
-
export type ApiApiHomeUserPassportrefreshAuthTokenMethod = 'post';
|
|
96
|
-
export type ApiApiHomeUserPassportrefreshAuthTokenRequestBody = {
|
|
97
|
-
refreshToken: string;
|
|
98
|
-
};
|
|
99
|
-
export type ApiApiHomeUserPassportrefreshAuthTokenResponseBody =
|
|
100
|
-
paths[ApiApiHomeUserPassportrefreshAuthTokenPath][ApiApiHomeUserPassportrefreshAuthTokenMethod]['responses']['200']['content']['application/json']['data'];
|
|
101
|
-
|
|
102
102
|
/** HomeUserPassport_createTempAuthToken */
|
|
103
103
|
export const ApiApiHomeUserPassportcreateTempAuthTokenPath =
|
|
104
104
|
'/api/home/user/passport/createTempAuthToken';
|
|
@@ -179,23 +179,23 @@ export class ApiHomeUserPassport extends BeanApiBase {
|
|
|
179
179
|
);
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
|
|
183
|
-
body:
|
|
182
|
+
refreshAuthToken(
|
|
183
|
+
body: ApiApiHomeUserPassportrefreshAuthTokenRequestBody,
|
|
184
184
|
options?: IApiActionOptions,
|
|
185
185
|
) {
|
|
186
|
-
return this.$fetch.post<any,
|
|
187
|
-
|
|
186
|
+
return this.$fetch.post<any, ApiApiHomeUserPassportrefreshAuthTokenResponseBody>(
|
|
187
|
+
ApiApiHomeUserPassportrefreshAuthTokenPath,
|
|
188
188
|
body,
|
|
189
189
|
this.$configPrepare(OpenApiBaseURL(this.sys), options),
|
|
190
190
|
);
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
|
|
194
|
-
body:
|
|
193
|
+
createPassportJwtFromOauthCode(
|
|
194
|
+
body: ApiApiHomeUserPassportcreatePassportJwtFromOauthCodeRequestBody,
|
|
195
195
|
options?: IApiActionOptions,
|
|
196
196
|
) {
|
|
197
|
-
return this.$fetch.post<any,
|
|
198
|
-
|
|
197
|
+
return this.$fetch.post<any, ApiApiHomeUserPassportcreatePassportJwtFromOauthCodeResponseBody>(
|
|
198
|
+
ApiApiHomeUserPassportcreatePassportJwtFromOauthCodePath,
|
|
199
199
|
body,
|
|
200
200
|
this.$configPrepare(OpenApiBaseURL(this.sys), options),
|
|
201
201
|
);
|