Skip to content

Commit 945ae18

Browse files
committed
Change auth actions to runtime enums
1 parent b47812d commit 945ae18

File tree

6 files changed

+49
-39
lines changed

6 files changed

+49
-39
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@
4949
"@nestjs/platform-fastify": "^11.1.0",
5050
"@patarapolw/prettyprint": "^1.0.3",
5151
"@seedcompany/cache": "^3.0.2",
52-
"@seedcompany/common": ">=0.17 <1",
52+
"@seedcompany/common": ">=0.19.1 <1",
5353
"@seedcompany/data-loader": "^2.0.1",
54-
"@seedcompany/nest": "^1.4.0",
54+
"@seedcompany/nest": "^1.6.1",
5555
"@seedcompany/nestjs-email": "^4.1.1",
5656
"@seedcompany/scripture": ">=0.8.0",
5757
"argon2": "^0.43.0",
Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,42 @@
1+
import { EnumType, makeEnum } from '@seedcompany/nest';
2+
13
/**
24
* Valid actions for resources
35
*/
4-
export type ResourceAction = 'read' | 'edit' | 'create' | 'delete';
6+
export type ResourceAction = EnumType<typeof ResourceAction>;
7+
export const ResourceAction = makeEnum(['read', 'edit', 'create', 'delete']);
58

69
/**
710
* Valid actions for properties
811
*/
9-
export type PropAction = 'read' | 'edit';
12+
export type PropAction = EnumType<typeof PropAction>;
13+
export const PropAction = makeEnum(['read', 'edit']);
1014

1115
/**
1216
* Valid actions for child relationships
1317
*/
14-
export type ChildRelationshipAction = 'read' | 'create' | 'delete';
18+
export type ChildRelationshipAction = EnumType<typeof ChildRelationshipAction>;
19+
export const ChildRelationshipAction = makeEnum(['read', 'create', 'delete']);
1520

1621
/**
1722
* Valid actions for child One-to-Many relationships
1823
*/
19-
export type ChildListAction = 'read' | 'create' | 'delete';
24+
export type ChildListAction = EnumType<typeof ChildListAction>;
25+
export const ChildListAction = makeEnum(['read', 'create', 'delete']);
2026

2127
/**
2228
* Valid actions for child One-to-One relationships
2329
*/
24-
export type ChildSingleAction = 'read' | 'edit';
30+
export type ChildSingleAction = EnumType<typeof ChildSingleAction>;
31+
export const ChildSingleAction = makeEnum(['read', 'edit']);
2532

2633
/**
2734
* Probably don't use directly
2835
* @internal
2936
*/
30-
export type AnyAction = ResourceAction | PropAction | ChildRelationshipAction;
37+
export type AnyAction = EnumType<typeof AnyAction>;
38+
export const AnyAction = makeEnum([
39+
...ResourceAction,
40+
...PropAction,
41+
...ChildRelationshipAction,
42+
]);

src/components/authorization/policy/executor/all-permissions-view.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { mapValues } from '@seedcompany/common';
2+
import { EnumType, makeEnum } from '@seedcompany/nest';
23
import { startCase } from 'lodash';
3-
import { keys as keysOf } from 'ts-transformer-keys';
44
import { PascalCase } from 'type-fest';
55
import {
66
ChildListsKey,
@@ -40,7 +40,7 @@ export const createAllPermissionsView = <
4040
getKeys: () => [...resource.securedPropsPlusExtra, ...resource.childKeys],
4141
calculate: (propName) =>
4242
createLazyRecord<Record<CompatAction, boolean>>({
43-
getKeys: () => keysOf<Record<CompatAction, boolean>>(),
43+
getKeys: () => CompatAction.values,
4444
calculate: (actionInput, propPerms) => {
4545
const action =
4646
actionInput === 'canEdit' &&
@@ -74,22 +74,26 @@ export const createAllPermissionsOfEdgeView = <
7474
calculate: (action) => privileges.can(action),
7575
});
7676

77-
type CompatAction = AnyAction | `can${PascalCase<AnyAction>}`;
77+
const asLegacyAction = (action: AnyAction) =>
78+
`can${startCase(action)}` as `can${PascalCase<AnyAction>}`;
79+
80+
type CompatAction = EnumType<typeof CompatAction>;
81+
const CompatAction = makeEnum([
82+
...AnyAction,
83+
...[...AnyAction].map(asLegacyAction),
84+
]);
7885

7986
const compatMap = {
8087
forward: {
8188
...mapValues.fromList(
82-
keysOf<Record<CompatAction, boolean>>(),
89+
CompatAction,
8390
(action) =>
8491
(action.startsWith('can')
8592
? action.slice(3).toLowerCase()
8693
: action) as AnyAction,
8794
).asRecord,
8895
},
8996
backward: {
90-
...mapValues.fromList(
91-
keysOf<Record<AnyAction, boolean>>(),
92-
(action) => `can${startCase(action)}` as CompatAction,
93-
).asRecord,
97+
...mapValues.fromList(AnyAction, asLegacyAction).asRecord,
9498
},
9599
};

src/components/authorization/policy/executor/policy-dumper.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { Command, Option } from 'clipanion';
1717
import { startCase } from 'lodash';
1818
import { DateTime } from 'luxon';
1919
import fs from 'node:fs/promises';
20-
import { keys as keysOf } from 'ts-transformer-keys';
2120
import { LiteralUnion } from 'type-fest';
2221
import { inspect } from 'util';
2322
import xlsx from 'xlsx';
@@ -188,16 +187,14 @@ export class PolicyDumper {
188187
role,
189188
resource,
190189
edge: undefined,
191-
...mapValues.fromList(
192-
keysOf<Record<ResourceAction, boolean>>(),
193-
(action) => resolve(action),
194-
).asRecord,
190+
...mapValues.fromList(ResourceAction, (action) => resolve(action))
191+
.asRecord,
195192
},
196193
...(options.props !== false
197194
? ([
198-
[resource.securedPropsPlusExtra, keysOf<Record<PropAction, ''>>()],
199-
[resource.childSingleKeys, keysOf<Record<ChildSingleAction, ''>>()],
200-
[resource.childListKeys, keysOf<Record<ChildListAction, ''>>()],
195+
[resource.securedPropsPlusExtra, PropAction],
196+
[resource.childSingleKeys, ChildSingleAction],
197+
[resource.childListKeys, ChildListAction],
201198
] as const)
202199
: []
203200
).flatMap(([set, actions]) =>

src/components/authorization/policy/policy.factory.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { Injectable, OnModuleInit } from '@nestjs/common';
66
import { entries, mapEntries, mapValues } from '@seedcompany/common';
77
import { pick, startCase } from 'lodash';
88
import { DeepWritable, Writable } from 'ts-essentials';
9-
import { keys as keysOf } from 'ts-transformer-keys';
109
import { EnhancedResource, many, Role } from '~/common';
1110
import { ResourcesHost } from '~/core/resources';
1211
import { Power } from '../dto';
@@ -314,13 +313,11 @@ export class PolicyFactory implements OnModuleInit {
314313
continue;
315314
}
316315

317-
const childActions = rel.list
318-
? keysOf<Record<ChildListAction, any>>()
319-
: keysOf<Record<ChildSingleAction, any>>();
316+
const childActions = rel.list ? ChildListAction : ChildSingleAction;
320317

321318
this.mergePermissions(
322319
(childRelations[rel.name] ??= {}),
323-
pick(grants.get(type)!.objectLevel, childActions),
320+
pick(grants.get(type)!.objectLevel, [...childActions]),
324321
);
325322
}
326323
}

yarn.lock

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3062,17 +3062,17 @@ __metadata:
30623062
languageName: node
30633063
linkType: hard
30643064

3065-
"@seedcompany/common@npm:>0.3 <1, @seedcompany/common@npm:>=0.17 <1, @seedcompany/common@npm:>=0.17 <1.0.0, @seedcompany/common@npm:>=0.3.0 <1.0.0":
3066-
version: 0.18.1
3067-
resolution: "@seedcompany/common@npm:0.18.1"
3065+
"@seedcompany/common@npm:>0.3 <1, @seedcompany/common@npm:>=0.17 <1, @seedcompany/common@npm:>=0.17 <1.0.0, @seedcompany/common@npm:>=0.19.1 <1, @seedcompany/common@npm:>=0.3.0 <1.0.0":
3066+
version: 0.19.1
3067+
resolution: "@seedcompany/common@npm:0.19.1"
30683068
dependencies:
30693069
type-fest: "npm:^4.37.0"
30703070
peerDependencies:
30713071
luxon: ^3.3.0
30723072
peerDependenciesMeta:
30733073
luxon:
30743074
optional: true
3075-
checksum: 10c0/54f1cdd5cf5b818ee6a8f1a3ca4e8379e26c2011abe132105cb117f3c207e47e316b8e3dab21e8eec682b56a7a08a20d60b6512b1ab35591a9e708a6703ea472
3075+
checksum: 10c0/d34e8591273ee4be08201b7a43c66240677027b155902e2558c8ed6d80274306d785b3675d3ecd68b6da2aa8adc831c23c71f62caa947e267573844abc3f92d8
30763076
languageName: node
30773077
linkType: hard
30783078

@@ -3127,9 +3127,9 @@ __metadata:
31273127
languageName: node
31283128
linkType: hard
31293129

3130-
"@seedcompany/nest@npm:^1.4.0":
3131-
version: 1.5.0
3132-
resolution: "@seedcompany/nest@npm:1.5.0"
3130+
"@seedcompany/nest@npm:^1.6.1":
3131+
version: 1.6.1
3132+
resolution: "@seedcompany/nest@npm:1.6.1"
31333133
dependencies:
31343134
"@nestjs/common": "npm:^10 || ^11"
31353135
"@nestjs/core": "npm:^10 || ^11"
@@ -3146,7 +3146,7 @@ __metadata:
31463146
"@nestjs/graphql": ^12 || ^13
31473147
class-transformer: ^0.5.1
31483148
reflect-metadata: ^0.1.12 || ^0.2.0
3149-
checksum: 10c0/80a1a6a4fab8a3ab39ceae617b26f082fddefd06db9b5f8ac33bfd2c61fd16160ac3fedb7c079d73e47a943b2670167676ad0cac848a3b4c4762ee6fdfc4f576
3149+
checksum: 10c0/ea820ab6a0fb245f36a6bc50f9c80f675488d1c46e4151ec38eb6cc10574e3a10bc8844c410ee9169fb5aae1e4ed3a95779c20404ae341f0f0c41ae5a4f20cdf
31503150
languageName: node
31513151
linkType: hard
31523152

@@ -5823,10 +5823,10 @@ __metadata:
58235823
"@nestjs/testing": "npm:^11.1.0"
58245824
"@patarapolw/prettyprint": "npm:^1.0.3"
58255825
"@seedcompany/cache": "npm:^3.0.2"
5826-
"@seedcompany/common": "npm:>=0.17 <1"
5826+
"@seedcompany/common": "npm:>=0.19.1 <1"
58275827
"@seedcompany/data-loader": "npm:^2.0.1"
58285828
"@seedcompany/eslint-plugin": "npm:^3.4.1"
5829-
"@seedcompany/nest": "npm:^1.4.0"
5829+
"@seedcompany/nest": "npm:^1.6.1"
58305830
"@seedcompany/nestjs-email": "npm:^4.1.1"
58315831
"@seedcompany/scripture": "npm:>=0.8.0"
58325832
"@tsconfig/strictest": "npm:^2.0.2"

0 commit comments

Comments
 (0)