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.
Files changed (66) hide show
  1. package/.cabloy-version +1 -1
  2. package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +1 -1
  3. package/CHANGELOG.md +9 -0
  4. package/CLAUDE.md +1 -0
  5. package/cabloy-docs/backend/controller-aop-guide.md +2 -2
  6. package/cabloy-docs/backend/field-indexes.md +10 -1
  7. package/cabloy-docs/backend/menu-guide.md +30 -0
  8. package/cabloy-docs/frontend/model-state-guide.md +2 -0
  9. package/cabloy-docs/frontend/use-state-data-best-practices.md +23 -0
  10. package/package.json +1 -1
  11. package/vona/packages-vona/vona/package.json +1 -1
  12. package/vona/pnpm-lock.yaml +27 -27
  13. package/vona/src/suite/a-home/modules/home-user/src/bean/eventListener.activate.ts +5 -4
  14. package/vona/src/suite/a-home/modules/home-user/src/bean/meta.version.ts +10 -6
  15. package/vona/src/suite/a-home/modules/home-user/src/config/config.ts +1 -1
  16. package/vona/src/suite/a-home/modules/home-user/src/entity/role.ts +4 -0
  17. package/vona/src/suite/a-home/modules/home-user/src/service/passportAdapter.ts +2 -2
  18. package/vona/src/suite/a-home/modules/home-user/src/service/roleAdapter.ts +5 -5
  19. package/vona/src/suite/a-training/modules/training-record/src/bean/ssrMenu.record.ts +1 -0
  20. package/vona/src/suite/a-training/modules/training-student/src/bean/ssrMenu.student.ts +1 -0
  21. package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/bean/ssrMenu.home.ts +1 -0
  22. package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/bean/ssrSite.admin.ts +5 -1
  23. package/vona/src/suite/cabloy-basic/modules/basic-siteweb/src/bean/ssrSite.web.ts +5 -1
  24. package/vona/src/suite-vendor/a-auth/modules/a-auth/package.json +1 -1
  25. package/vona/src/suite-vendor/a-auth/modules/a-auth/src/service/auth.ts +5 -1
  26. package/vona/src/suite-vendor/a-auth/package.json +1 -1
  27. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/cli/ssrSite/boilerplate/{{sceneName}}.{{beanName}}.ts_ +5 -3
  28. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
  29. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/bean/event.retrieveMenusSite.ts +2 -2
  30. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/lib/beanSsrSiteBase.ts +33 -8
  31. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/service/ssr.ts +46 -16
  32. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/service/ssrHandler.ts +2 -4
  33. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/env.ts +1 -0
  34. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/ssrMenu.ts +10 -1
  35. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/ssrSite.ts +3 -1
  36. package/vona/src/suite-vendor/a-cabloy/package.json +1 -1
  37. package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
  38. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/.metadata/index.ts +18 -2
  39. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +6 -1
  40. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/event.retrievePermissionAction.ts +16 -0
  41. package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
  42. package/vona/src/suite-vendor/a-vona/modules/a-user/src/bean/bean.passport.ts +2 -2
  43. package/vona/src/suite-vendor/a-vona/modules/a-user/src/lib/passport.ts +7 -4
  44. package/vona/src/suite-vendor/a-vona/modules/a-user/src/types/passport.ts +1 -1
  45. package/vona/src/suite-vendor/a-vona/modules/a-user/src/types/role.ts +3 -1
  46. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  47. package/zova/env/.env.cabloyBasicAdmin +2 -0
  48. package/zova/env/.env.cabloyBasicWeb +2 -0
  49. package/zova/packages-utils/zova-jsx/package.json +2 -2
  50. package/zova/packages-zova/zova/package.json +3 -3
  51. package/zova/packages-zova/zova-core/package.json +1 -1
  52. package/zova/packages-zova/zova-core/src/core/sys/sys.ts +3 -0
  53. package/zova/packages-zova/zova-core/src/types/utils/env.ts +1 -0
  54. package/zova/src/suite/a-home/modules/home-api/src/api/homeUserPassport.ts +19 -19
  55. package/zova/src/suite/a-home/modules/home-api/src/api/openapi/types.ts +11 -10
  56. package/zova/src/suite/a-home/modules/home-api/src/apiSchema/homeUserPassport.ts +5 -5
  57. package/zova/src/suite/a-home/modules/home-base/src/.metadata/page/errorAccessDenied.ts +9 -0
  58. package/zova/src/suite/a-home/modules/home-base/src/page/errorAccessDenied/controller.tsx +40 -0
  59. package/zova/src/suite/a-home/modules/home-base/src/routes.ts +9 -0
  60. package/zova/src/suite/a-home/modules/home-base/src/service/routerGuards.ts +21 -12
  61. package/zova/src/suite/a-home/modules/home-passport/src/model/passport.ts +2 -2
  62. package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
  63. package/zova/src/suite-vendor/a-zova/modules/a-router/src/monkeySys.ts +10 -1
  64. package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/router.ts +1 -0
  65. package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
  66. package/zova/src/suite-vendor/a-zova/package.json +3 -3
@@ -256,7 +256,7 @@ export interface paths {
256
256
  patch?: never;
257
257
  trace?: never;
258
258
  };
259
- '/api/home/user/passport/createPassportJwtFromOauthCode': {
259
+ '/api/home/user/passport/refreshAuthToken': {
260
260
  parameters: {
261
261
  query?: never;
262
262
  header?: never;
@@ -265,14 +265,14 @@ export interface paths {
265
265
  };
266
266
  get?: never;
267
267
  put?: never;
268
- post: operations['HomeUserPassport_createPassportJwtFromOauthCode'];
268
+ post: operations['HomeUserPassport_refreshAuthToken'];
269
269
  delete?: never;
270
270
  options?: never;
271
271
  head?: never;
272
272
  patch?: never;
273
273
  trace?: never;
274
274
  };
275
- '/api/home/user/passport/refreshAuthToken': {
275
+ '/api/home/user/passport/createPassportJwtFromOauthCode': {
276
276
  parameters: {
277
277
  query?: never;
278
278
  header?: never;
@@ -281,7 +281,7 @@ export interface paths {
281
281
  };
282
282
  get?: never;
283
283
  put?: never;
284
- post: operations['HomeUserPassport_refreshAuthToken'];
284
+ post: operations['HomeUserPassport_createPassportJwtFromOauthCode'];
285
285
  delete?: never;
286
286
  options?: never;
287
287
  head?: never;
@@ -1531,6 +1531,7 @@ export interface components {
1531
1531
  id: number | string;
1532
1532
  /** @description Role Name */
1533
1533
  name: string;
1534
+ siteIds: string[];
1534
1535
  };
1535
1536
  'home-user.dto.passportJwt': {
1536
1537
  passport: components['schemas']['home-user.dto.passport'];
@@ -3373,7 +3374,7 @@ export interface operations {
3373
3374
  };
3374
3375
  authToken: true;
3375
3376
  };
3376
- HomeUserPassport_createPassportJwtFromOauthCode: {
3377
+ HomeUserPassport_refreshAuthToken: {
3377
3378
  parameters: {
3378
3379
  query?: never;
3379
3380
  header?: never;
@@ -3383,7 +3384,7 @@ export interface operations {
3383
3384
  requestBody: {
3384
3385
  content: {
3385
3386
  'application/json': {
3386
- code: string;
3387
+ refreshToken: string;
3387
3388
  };
3388
3389
  };
3389
3390
  };
@@ -3396,13 +3397,13 @@ export interface operations {
3396
3397
  'application/json': {
3397
3398
  code: string;
3398
3399
  message: string;
3399
- data: components['schemas']['home-user.dto.passportJwt'];
3400
+ data: components['schemas']['a-jwt.dto.jwtToken'];
3400
3401
  };
3401
3402
  };
3402
3403
  };
3403
3404
  };
3404
3405
  };
3405
- HomeUserPassport_refreshAuthToken: {
3406
+ HomeUserPassport_createPassportJwtFromOauthCode: {
3406
3407
  parameters: {
3407
3408
  query?: never;
3408
3409
  header?: never;
@@ -3412,7 +3413,7 @@ export interface operations {
3412
3413
  requestBody: {
3413
3414
  content: {
3414
3415
  'application/json': {
3415
- refreshToken: string;
3416
+ code: string;
3416
3417
  };
3417
3418
  };
3418
3419
  };
@@ -3425,7 +3426,7 @@ export interface operations {
3425
3426
  'application/json': {
3426
3427
  code: string;
3427
3428
  message: string;
3428
- data: components['schemas']['a-jwt.dto.jwtToken'];
3429
+ data: components['schemas']['home-user.dto.passportJwt'];
3429
3430
  };
3430
3431
  };
3431
3432
  };
@@ -11,8 +11,8 @@ import {
11
11
  ApiApiHomeUserPassportloginOauthPath,
12
12
  ApiApiHomeUserPassportassociatePath,
13
13
  ApiApiHomeUserPassportmigratePath,
14
- ApiApiHomeUserPassportcreatePassportJwtFromOauthCodePath,
15
14
  ApiApiHomeUserPassportrefreshAuthTokenPath,
15
+ ApiApiHomeUserPassportcreatePassportJwtFromOauthCodePath,
16
16
  ApiApiHomeUserPassportcreateTempAuthTokenPath,
17
17
  } from '../api/homeUserPassport.js';
18
18
 
@@ -46,6 +46,10 @@ export class ApiSchemaHomeUserPassport extends BeanBase {
46
46
  return this.$sdk.createApiSchemas(ApiApiHomeUserPassportmigratePath, 'get', options);
47
47
  }
48
48
 
49
+ refreshAuthToken(options?: IApiSchemaOptions) {
50
+ return this.$sdk.createApiSchemas(ApiApiHomeUserPassportrefreshAuthTokenPath, 'post', options);
51
+ }
52
+
49
53
  createPassportJwtFromOauthCode(options?: IApiSchemaOptions) {
50
54
  return this.$sdk.createApiSchemas(
51
55
  ApiApiHomeUserPassportcreatePassportJwtFromOauthCodePath,
@@ -54,10 +58,6 @@ export class ApiSchemaHomeUserPassport extends BeanBase {
54
58
  );
55
59
  }
56
60
 
57
- refreshAuthToken(options?: IApiSchemaOptions) {
58
- return this.$sdk.createApiSchemas(ApiApiHomeUserPassportrefreshAuthTokenPath, 'post', options);
59
- }
60
-
61
61
  createTempAuthToken(options?: IApiSchemaOptions) {
62
62
  return this.$sdk.createApiSchemas(
63
63
  ApiApiHomeUserPassportcreateTempAuthTokenPath,
@@ -0,0 +1,9 @@
1
+ import { createZovaComponentPage } from 'zova';
2
+
3
+ import { ControllerPageErrorAccessDenied } from '../../page/errorAccessDenied/controller.jsx';
4
+
5
+ export const ZPageErrorAccessDenied = createZovaComponentPage(
6
+ ControllerPageErrorAccessDenied,
7
+ undefined,
8
+ undefined,
9
+ );
@@ -0,0 +1,40 @@
1
+ import { classes } from 'typestyle';
2
+ import { BeanControllerPageBase } from 'zova';
3
+ import { Controller } from 'zova-module-a-bean';
4
+
5
+ @Controller()
6
+ export class ControllerPageErrorAccessDenied extends BeanControllerPageBase {
7
+ cTitle: string;
8
+ cDescription: string;
9
+
10
+ protected async __init__() {
11
+ this.cTitle = this.$style({
12
+ fontSize: '30vh',
13
+ });
14
+ this.cDescription = classes(
15
+ 'text-3xl',
16
+ this.$style({
17
+ opacity: '0.4',
18
+ }),
19
+ );
20
+ }
21
+
22
+ protected render() {
23
+ return (
24
+ <div class="text-center">
25
+ <div>
26
+ <div class={this.cTitle}>403</div>
27
+ <div class={this.cDescription}>Access denied.</div>
28
+ <button
29
+ class="btn btn-primary"
30
+ onClick={() => {
31
+ this.app.$gotoHome();
32
+ }}
33
+ >
34
+ Go Home
35
+ </button>
36
+ </div>
37
+ </div>
38
+ );
39
+ }
40
+ }
@@ -1,6 +1,7 @@
1
1
  import type { IModuleRoute } from 'zova-module-a-router';
2
2
 
3
3
  import { ZPageAuthCallback } from './.metadata/page/authCallback.js';
4
+ import { ZPageErrorAccessDenied } from './.metadata/page/errorAccessDenied.js';
4
5
  import { ZPageErrorExpired } from './.metadata/page/errorExpired.js';
5
6
  import { ZPageErrorNotFound } from './.metadata/page/errorNotFound.js';
6
7
 
@@ -14,6 +15,14 @@ export const routes: IModuleRoute[] = [
14
15
  requiresAuth: false,
15
16
  },
16
17
  },
18
+ {
19
+ path: 'errorAccessDenied',
20
+ component: ZPageErrorAccessDenied,
21
+ meta: {
22
+ layout: 'empty',
23
+ requiresAuth: false,
24
+ },
25
+ },
17
26
  {
18
27
  path: 'errorNotFound',
19
28
  component: ZPageErrorNotFound,
@@ -14,11 +14,9 @@ export class ServiceRouterGuards extends BeanRouterGuardsBase {
14
14
 
15
15
  protected onRouterGuards(router: BeanRouter) {
16
16
  router.beforeEach(async to => {
17
- if (
18
- !this.sys.config.ssr.cookieDisabledOnServer &&
19
- to.meta.requiresAuth !== false &&
20
- !this.$passport.isAuthenticated
21
- ) {
17
+ if (to.meta.requiresAuth === false) return;
18
+ if (this.sys.config.ssr.cookieDisabledOnServer) return;
19
+ if (!this.$passport.isAuthenticated) {
22
20
  const [_res, err] = await catchError(() => {
23
21
  return this.$passport.ensurePassport();
24
22
  });
@@ -26,14 +24,25 @@ export class ServiceRouterGuards extends BeanRouterGuardsBase {
26
24
  this.$errorHandler(err, 'onRouterGuards');
27
25
  return false;
28
26
  }
29
- if (!this.$passport.isAuthenticated) {
30
- try {
31
- this.app.$gotoLogin(to.fullPath);
32
- } catch (err: any) {
33
- this.$errorHandler(err);
34
- }
35
- return false;
27
+ }
28
+ if (!this.$passport.isAuthenticated) {
29
+ try {
30
+ this.app.$gotoLogin(to.fullPath);
31
+ } catch (err: any) {
32
+ this.$errorHandler(err);
33
+ }
34
+ return false;
35
+ }
36
+ const siteId = this.sys.env.SITE_ID;
37
+ const siteAdmitted =
38
+ !!siteId && !!this.$passport.roles?.some(role => role.siteIds.includes(siteId));
39
+ if (!siteAdmitted) {
40
+ try {
41
+ this.app.$gotoAccessDenied();
42
+ } catch (err: any) {
43
+ this.$errorHandler(err);
36
44
  }
45
+ return false;
37
46
  }
38
47
  });
39
48
  router.beforeResolve(async to => {
@@ -169,8 +169,8 @@ export class ModelPassport extends BeanModelBase {
169
169
  return this.passport?.roles;
170
170
  }
171
171
 
172
- get isAdmin() {
173
- return !!this.passport?.roles.some(item => item.name === 'admin');
172
+ get isSystemAdmin() {
173
+ return !!this.passport?.roles.some(item => item.name === 'systemAdmin');
174
174
  }
175
175
 
176
176
  async getJwtInfo(): Promise<IJwtInfo | undefined> {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-router",
3
- "version": "5.1.29",
3
+ "version": "5.1.30",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "router",
6
6
  "keywords": [
@@ -85,8 +85,12 @@ export class MonkeySys
85
85
  return app.$gotoPage(pagePath, { ...options, params: undefined });
86
86
  };
87
87
  app.$gotoLogin = (returnTo?: string, cause?: string) => {
88
- if (!returnTo && cast(app.meta.$router.currentRoute)?.path === app.sys.env.ROUTER_PAGE_LOGIN)
88
+ if (
89
+ !returnTo &&
90
+ cast(app.meta.$router.currentRoute)?.path === app.sys.env.ROUTER_PAGE_LOGIN
91
+ ) {
89
92
  return;
93
+ }
90
94
  const query: any = {};
91
95
  if (cause) {
92
96
  query.cause = cause;
@@ -94,6 +98,11 @@ export class MonkeySys
94
98
  const returnTo2 = returnTo === app.sys.env.ROUTER_PAGE_LOGIN ? undefined : (returnTo ?? true);
95
99
  return app.$gotoPage(app.sys.env.ROUTER_PAGE_LOGIN, { query, returnTo: returnTo2 });
96
100
  };
101
+ app.$gotoAccessDenied = () => {
102
+ const pagePath = '/home/base/errorAccessDenied';
103
+ if (cast(app.meta.$router.currentRoute)?.path === pagePath) return;
104
+ return app.$gotoPage(pagePath, { replace: true });
105
+ };
97
106
  app.$gotoReturnTo = (returnTo?: string) => {
98
107
  const pagePath = app.$getReturnTo(returnTo);
99
108
  return app.$gotoPage(pagePath, { replace: true });
@@ -52,6 +52,7 @@ declare module 'zova' {
52
52
  $gotoPage(pagePath: string, options?: IGotoPageOptions): TypeGotoPageResult;
53
53
  $gotoHome(options?: IGotoPageOptions): TypeGotoPageResult;
54
54
  $gotoLogin(returnTo?: string, cause?: string): TypeGotoPageResult;
55
+ $gotoAccessDenied(): TypeGotoPageResult;
55
56
  $gotoReturnTo(returnTo?: string): TypeGotoPageResult;
56
57
  $getReturnTo(returnTo?: string): string;
57
58
  $getCurrentPagePath(): string | undefined;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-zova",
3
- "version": "5.1.92",
3
+ "version": "5.1.93",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "zova",
6
6
  "keywords": [
@@ -43,7 +43,7 @@
43
43
  "@cabloy/word-utils": "^2.1.14",
44
44
  "defu": "^6.1.7",
45
45
  "luxon": "^3.7.2",
46
- "zova-jsx": "^1.1.77"
46
+ "zova-jsx": "^1.1.78"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@cabloy/cli": "^3.1.28",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-suite-a-zova",
3
- "version": "5.1.133",
3
+ "version": "5.1.134",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "zova",
6
6
  "license": "MIT",
@@ -23,7 +23,7 @@
23
23
  "zova-module-a-meta": "^5.1.21",
24
24
  "zova-module-a-model": "^5.1.33",
25
25
  "zova-module-a-openapi": "^5.1.43",
26
- "zova-module-a-router": "^5.1.29",
26
+ "zova-module-a-router": "^5.1.30",
27
27
  "zova-module-a-routerstack": "^5.1.26",
28
28
  "zova-module-a-routertabs": "^5.1.33",
29
29
  "zova-module-a-ssr": "^5.1.29",
@@ -32,7 +32,7 @@
32
32
  "zova-module-a-style": "^5.1.32",
33
33
  "zova-module-a-table": "^5.1.37",
34
34
  "zova-module-a-zod": "^5.1.36",
35
- "zova-module-a-zova": "^5.1.92"
35
+ "zova-module-a-zova": "^5.1.93"
36
36
  },
37
37
  "title": "a-zova"
38
38
  }