vona-cli-set-api 1.1.126 → 1.1.128

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.
@@ -20,6 +20,7 @@ export interface ISsrMenuOptions<%=argv.resourceNameCapitalize%> extends IDecora
20
20
  },
21
21
  },
22
22
  group: '<%=argv.ssrSiteGroupName%>',
23
+ roles: ['systemAdmin'],
23
24
  },
24
25
  },
25
26
  site: ['<%=argv.ssrSiteOnionName%>'],
@@ -4,6 +4,8 @@ import type { IDecoratorControllerOptions } from 'vona-module-a-web';
4
4
 
5
5
  import { BeanBase } from 'vona';
6
6
  import { Api, Resource, v } from 'vona-module-a-openapiutils';
7
+ import { z } from 'zod';
8
+ import { Passport } from 'vona-module-a-user';
7
9
  import { Arg, Controller, Web } from 'vona-module-a-web';
8
10
 
9
11
  import type { Model<%=argv.resourceNameCapitalize%> } from '../model/<%=argv.resourceName%>.ts';
@@ -21,29 +23,36 @@ export interface IControllerOptions<%=argv.resourceNameCapitalize%> extends IDec
21
23
  export class Controller<%=argv.resourceNameCapitalize%> extends BeanBase {
22
24
  @Web.post()
23
25
  @Api.body(v.tableIdentity())
26
+ @Passport.systemAdmin()
24
27
  async create(@Arg.body() <%=argv.resourceName%>: Dto<%=argv.resourceNameCapitalize%>Create): Promise<TableIdentity> {
25
28
  return (await this.scope.service.<%=argv.resourceName%>.create(<%=argv.resourceName%>)).id;
26
29
  }
27
30
 
28
31
  @Web.get()
29
32
  @Api.body(Dto<%=argv.resourceNameCapitalize%>SelectRes)
33
+ @Passport.systemAdmin()
30
34
  async select(@Arg.filter(Dto<%=argv.resourceNameCapitalize%>SelectReq) params: IQueryParams<Model<%=argv.resourceNameCapitalize%>>): Promise<Dto<%=argv.resourceNameCapitalize%>SelectRes> {
31
35
  return await this.scope.service.<%=argv.resourceName%>.select(params);
32
36
  }
33
37
 
34
38
  @Web.get(':id')
35
39
  @Api.body(v.optional(), v.object(Dto<%=argv.resourceNameCapitalize%>View))
40
+ @Passport.systemAdmin()
36
41
  async view(@Arg.param('id', v.tableIdentity()) id: TableIdentity): Promise<Dto<%=argv.resourceNameCapitalize%>View | undefined> {
37
42
  return await this.scope.service.<%=argv.resourceName%>.view(id);
38
43
  }
39
44
 
40
45
  @Web.patch(':id')
41
- async update(@Arg.param('id', v.tableIdentity()) id: TableIdentity, @Arg.body() <%=argv.resourceName%>: Dto<%=argv.resourceNameCapitalize%>Update) {
42
- return await this.scope.service.<%=argv.resourceName%>.update(id, <%=argv.resourceName%>);
46
+ @Api.body(z.null())
47
+ @Passport.systemAdmin()
48
+ async update(@Arg.param('id', v.tableIdentity()) id: TableIdentity, @Arg.body() <%=argv.resourceName%>: Dto<%=argv.resourceNameCapitalize%>Update): Promise<void> {
49
+ await this.scope.service.<%=argv.resourceName%>.update(id, <%=argv.resourceName%>);
43
50
  }
44
51
 
45
52
  @Web.delete(':id')
46
- async delete(@Arg.param('id', v.tableIdentity()) id: TableIdentity) {
47
- return await this.scope.service.<%=argv.resourceName%>.delete(id);
53
+ @Api.body(z.null())
54
+ @Passport.systemAdmin()
55
+ async delete(@Arg.param('id', v.tableIdentity()) id: TableIdentity): Promise<void> {
56
+ await this.scope.service.<%=argv.resourceName%>.delete(id);
48
57
  }
49
58
  }
@@ -15,7 +15,24 @@ describe('<%=argv.resourceName%>.test.ts', () => {
15
15
  name: '__TomNew__',
16
16
  description: 'This is a test',
17
17
  };
18
- // login
18
+ // role-less authenticated users cannot access generated admin actions
19
+ await app.bean.passport.signinMock();
20
+ try {
21
+ app.bean.passport.current!.roles = [];
22
+ const actions = ['create', 'select', 'view', 'update', 'delete'];
23
+ const permissions = await Promise.all(
24
+ actions.map(action =>
25
+ app.bean.permission.retrievePermissionAction(
26
+ '<%=argv.moduleInfo.relativeName%>:<%=argv.resourceName%>',
27
+ action,
28
+ ),
29
+ ),
30
+ );
31
+ assert.deepEqual(permissions, actions.map(() => false));
32
+ } finally {
33
+ await app.bean.passport.signout();
34
+ }
35
+ // login as system admin
19
36
  await app.bean.passport.signinMock();
20
37
  // create
21
38
  const <%=argv.resourceName%>Id = await app.bean.executor.performAction('post', '<%=argv.moduleActionPathRaw%>', { body: data });
@@ -24,15 +41,17 @@ describe('<%=argv.resourceName%>.test.ts', () => {
24
41
  const selectRes: Dto<%=argv.resourceNameCapitalize%>SelectRes = await app.bean.executor.performAction('get', '<%=argv.moduleActionPathRaw%>');
25
42
  assert.equal(selectRes.list.findIndex(item => item.name === data.name) > -1, true);
26
43
  // update
27
- await app.bean.executor.performAction('patch', '<%=argv.moduleActionPathRaw%>/:id', {
44
+ const updateRes = await app.bean.executor.performAction('patch', '<%=argv.moduleActionPathRaw%>/:id', {
28
45
  params: { id: <%=argv.resourceName%>Id },
29
46
  body: dataUpdate,
30
47
  });
48
+ assert.equal(updateRes, null);
31
49
  // findOne
32
50
  let <%=argv.resourceName%>: Entity<%=argv.resourceNameCapitalize%> = await app.bean.executor.performAction('get', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>Id } });
33
51
  assert.equal(<%=argv.resourceName%>.name, dataUpdate.name);
34
52
  // delete
35
- await app.bean.executor.performAction('delete', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>.id } });
53
+ const deleteRes = await app.bean.executor.performAction('delete', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>.id } });
54
+ assert.equal(deleteRes, null);
36
55
  // findOne
37
56
  <%=argv.resourceName%> = await app.bean.executor.performAction('get', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>.id } });
38
57
  assert.equal(<%=argv.resourceName%>, undefined);
@@ -4,6 +4,8 @@ import type { IDecoratorControllerOptions } from 'vona-module-a-web';
4
4
 
5
5
  import { BeanBase } from 'vona';
6
6
  import { Api, Resource, v } from 'vona-module-a-openapiutils';
7
+ import { z } from 'zod';
8
+ import { Passport } from 'vona-module-a-user';
7
9
  import { Arg, Controller, Web } from 'vona-module-a-web';
8
10
 
9
11
  import type { Model<%=argv.resourceNameCapitalize%> } from '../model/<%=argv.resourceName%>.ts';
@@ -21,29 +23,36 @@ export interface IControllerOptions<%=argv.resourceNameCapitalize%> extends IDec
21
23
  export class Controller<%=argv.resourceNameCapitalize%> extends BeanBase {
22
24
  @Web.post()
23
25
  @Api.body(v.tableIdentity())
26
+ @Passport.systemAdmin()
24
27
  async create(@Arg.body() <%=argv.resourceName%>: Dto<%=argv.resourceNameCapitalize%>Create): Promise<TableIdentity> {
25
28
  return (await this.scope.service.<%=argv.resourceName%>.create(<%=argv.resourceName%>)).id;
26
29
  }
27
30
 
28
31
  @Web.get()
29
32
  @Api.body(Dto<%=argv.resourceNameCapitalize%>SelectRes)
33
+ @Passport.systemAdmin()
30
34
  async select(@Arg.filter(Dto<%=argv.resourceNameCapitalize%>SelectReq) params: IQueryParams<Model<%=argv.resourceNameCapitalize%>>): Promise<Dto<%=argv.resourceNameCapitalize%>SelectRes> {
31
35
  return await this.scope.service.<%=argv.resourceName%>.select(params);
32
36
  }
33
37
 
34
38
  @Web.get(':id')
35
39
  @Api.body(v.optional(), v.object(Dto<%=argv.resourceNameCapitalize%>View))
40
+ @Passport.systemAdmin()
36
41
  async view(@Arg.param('id', v.tableIdentity()) id: TableIdentity): Promise<Dto<%=argv.resourceNameCapitalize%>View | undefined> {
37
42
  return await this.scope.service.<%=argv.resourceName%>.view(id);
38
43
  }
39
44
 
40
45
  @Web.patch(':id')
41
- async update(@Arg.param('id', v.tableIdentity()) id: TableIdentity, @Arg.body() <%=argv.resourceName%>: Dto<%=argv.resourceNameCapitalize%>Update) {
42
- return await this.scope.service.<%=argv.resourceName%>.update(id, <%=argv.resourceName%>);
46
+ @Api.body(z.null())
47
+ @Passport.systemAdmin()
48
+ async update(@Arg.param('id', v.tableIdentity()) id: TableIdentity, @Arg.body() <%=argv.resourceName%>: Dto<%=argv.resourceNameCapitalize%>Update): Promise<void> {
49
+ await this.scope.service.<%=argv.resourceName%>.update(id, <%=argv.resourceName%>);
43
50
  }
44
51
 
45
52
  @Web.delete(':id')
46
- async delete(@Arg.param('id', v.tableIdentity()) id: TableIdentity) {
47
- return await this.scope.service.<%=argv.resourceName%>.delete(id);
53
+ @Api.body(z.null())
54
+ @Passport.systemAdmin()
55
+ async delete(@Arg.param('id', v.tableIdentity()) id: TableIdentity): Promise<void> {
56
+ await this.scope.service.<%=argv.resourceName%>.delete(id);
48
57
  }
49
58
  }
@@ -15,7 +15,24 @@ describe('<%=argv.resourceName%>.test.ts', () => {
15
15
  name: '__TomNew__',
16
16
  description: 'This is a test',
17
17
  };
18
- // login
18
+ // role-less authenticated users cannot access generated admin actions
19
+ await app.bean.passport.signinMock();
20
+ try {
21
+ app.bean.passport.current!.roles = [];
22
+ const actions = ['create', 'select', 'view', 'update', 'delete'];
23
+ const permissions = await Promise.all(
24
+ actions.map(action =>
25
+ app.bean.permission.retrievePermissionAction(
26
+ '<%=argv.moduleInfo.relativeName%>:<%=argv.resourceName%>',
27
+ action,
28
+ ),
29
+ ),
30
+ );
31
+ assert.deepEqual(permissions, actions.map(() => false));
32
+ } finally {
33
+ await app.bean.passport.signout();
34
+ }
35
+ // login as system admin
19
36
  await app.bean.passport.signinMock();
20
37
  // create
21
38
  const <%=argv.resourceName%>Id = await app.bean.executor.performAction('post', '<%=argv.moduleActionPathRaw%>', { body: data });
@@ -24,15 +41,17 @@ describe('<%=argv.resourceName%>.test.ts', () => {
24
41
  const selectRes: Dto<%=argv.resourceNameCapitalize%>SelectRes = await app.bean.executor.performAction('get', '<%=argv.moduleActionPathRaw%>');
25
42
  assert.equal(selectRes.list.findIndex(item => item.name === data.name) > -1, true);
26
43
  // update
27
- await app.bean.executor.performAction('patch', '<%=argv.moduleActionPathRaw%>/:id', {
44
+ const updateRes = await app.bean.executor.performAction('patch', '<%=argv.moduleActionPathRaw%>/:id', {
28
45
  params: { id: <%=argv.resourceName%>Id },
29
46
  body: dataUpdate,
30
47
  });
48
+ assert.equal(updateRes, null);
31
49
  // findOne
32
50
  let <%=argv.resourceName%>: Entity<%=argv.resourceNameCapitalize%> = await app.bean.executor.performAction('get', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>Id } });
33
51
  assert.equal(<%=argv.resourceName%>.name, dataUpdate.name);
34
52
  // delete
35
- await app.bean.executor.performAction('delete', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>.id } });
53
+ const deleteRes = await app.bean.executor.performAction('delete', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>.id } });
54
+ assert.equal(deleteRes, null);
36
55
  // findOne
37
56
  <%=argv.resourceName%> = await app.bean.executor.performAction('get', '<%=argv.moduleActionPathRaw%>/:id', { params: { id: <%=argv.resourceName%>.id } });
38
57
  assert.equal(<%=argv.resourceName%>, undefined);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vona-cli-set-api",
3
- "version": "1.1.126",
4
- "gitHead": "7a711c5f09e0c1d3b0fda2084710297ea45b5d8e",
3
+ "version": "1.1.128",
4
+ "gitHead": "93d6ccaace7d8eca543adb7b2dd0b295603eeec0",
5
5
  "description": "vona cli-set-api",
6
6
  "keywords": [
7
7
  "framework",
@@ -73,7 +73,7 @@
73
73
  "ts-node-maintained": "^10.9.6",
74
74
  "urllib": "^4.9.0",
75
75
  "uuid": "^11.1.0",
76
- "vona-core": "^5.1.31",
76
+ "vona-core": "^5.1.32",
77
77
  "why-is-node-running": "^3.2.2",
78
78
  "yargs-parser": "^22.0.0"
79
79
  }