@via-profit/ability 2.0.0-rc.8 → 3.0.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/CHANGELOG.md +64 -0
- package/CONTRIBUTING.md +14 -0
- package/LICENSE +21 -0
- package/README.md +1081 -166
- package/SECURITY.md +33 -0
- package/dist/AbilityCode.d.ts +6 -6
- package/dist/AbilityCompare.d.ts +2 -2
- package/dist/AbilityCondition.d.ts +13 -10
- package/dist/AbilityError.d.ts +0 -3
- package/dist/AbilityExplain.d.ts +27 -0
- package/dist/AbilityMatch.d.ts +2 -2
- package/dist/AbilityParser.d.ts +45 -4
- package/dist/AbilityPolicy.d.ts +23 -12
- package/dist/AbilityPolicyEffect.d.ts +2 -2
- package/dist/AbilityResolver.d.ts +2 -0
- package/dist/AbilityRule.d.ts +28 -5
- package/dist/AbilityRuleSet.d.ts +15 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.js +441 -101
- package/package.json +11 -3
- package/assets/ability-01.drawio.png +0 -0
- package/build/playground.js +0 -814
- package/build/playground.js.map +0 -1
- package/dist/AbilityPolicyResult.d.ts +0 -6
- package/dist/playground.d.ts +0 -26
package/SECURITY.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a Vulnerability
|
|
4
|
+
|
|
5
|
+
I take the security of `@via-profit/ability` seriously. If you discover a security vulnerability, please report it responsibly.
|
|
6
|
+
|
|
7
|
+
### How to Report a Vulnerability
|
|
8
|
+
|
|
9
|
+
**Please DO NOT create a public GitHub issue for security vulnerabilities.**
|
|
10
|
+
|
|
11
|
+
Instead, send the details directly to me:
|
|
12
|
+
|
|
13
|
+
- **Email**: [delhsmail@gmail.com](mailto:delhsmail@gmail.com)
|
|
14
|
+
- **Author**: Vasily Novosad
|
|
15
|
+
- **Timezone**: UTC+5 (for coordinating response time)
|
|
16
|
+
|
|
17
|
+
### What to Include
|
|
18
|
+
|
|
19
|
+
To help me address the issue quickly, please include:
|
|
20
|
+
|
|
21
|
+
- Description of the vulnerability
|
|
22
|
+
- Steps to reproduce (if applicable)
|
|
23
|
+
- Potential impact
|
|
24
|
+
- Suggestions for fixing (if any)
|
|
25
|
+
|
|
26
|
+
### Process
|
|
27
|
+
|
|
28
|
+
1. I will acknowledge your report within 48 hours
|
|
29
|
+
2. I will assess the vulnerability
|
|
30
|
+
3. Work on a fix will begin depending on severity
|
|
31
|
+
4. After the fix is released, I will notify you and acknowledge your contribution (if you agree)
|
|
32
|
+
|
|
33
|
+
Thank you for helping keep this project secure!
|
package/dist/AbilityCode.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export declare class AbilityCode<
|
|
2
|
-
|
|
3
|
-
constructor(code:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
export declare class AbilityCode<Code extends string | number> {
|
|
2
|
+
_code: Code;
|
|
3
|
+
constructor(code: Code);
|
|
4
|
+
get code(): Code;
|
|
5
|
+
isEqual(compareWith: AbilityCode<Code> | null): boolean;
|
|
6
|
+
isNotEqual(compareWith: AbilityCode<Code> | null): boolean;
|
|
7
7
|
}
|
|
8
8
|
export default AbilityCode;
|
package/dist/AbilityCompare.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import AbilityCode from './AbilityCode';
|
|
2
|
-
export type
|
|
3
|
-
export declare class AbilityCompare extends AbilityCode<
|
|
2
|
+
export type AbilityCompareCodeType = 'and' | 'or';
|
|
3
|
+
export declare class AbilityCompare extends AbilityCode<AbilityCompareCodeType> {
|
|
4
4
|
static and: AbilityCompare;
|
|
5
5
|
static or: AbilityCompare;
|
|
6
6
|
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import AbilityCode from './AbilityCode';
|
|
2
|
-
export type
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
static
|
|
6
|
-
static
|
|
7
|
-
static
|
|
8
|
-
static
|
|
9
|
-
static
|
|
10
|
-
static
|
|
11
|
-
static
|
|
2
|
+
export type AbilityConditionCodeType = '=' | '<>' | '>' | '<' | '>=' | '<=' | 'in' | 'not in';
|
|
3
|
+
export type AbilityConditionLiteralType = 'equal' | 'not_equal' | 'more_than' | 'less_than' | 'less_or_equal' | 'more_or_equal' | 'in' | 'not_in';
|
|
4
|
+
export declare class AbilityCondition extends AbilityCode<AbilityConditionCodeType> {
|
|
5
|
+
static equal: AbilityCondition;
|
|
6
|
+
static not_equal: AbilityCondition;
|
|
7
|
+
static more_than: AbilityCondition;
|
|
8
|
+
static less_than: AbilityCondition;
|
|
9
|
+
static less_or_equal: AbilityCondition;
|
|
10
|
+
static more_or_equal: AbilityCondition;
|
|
11
|
+
static in: AbilityCondition;
|
|
12
|
+
static not_in: AbilityCondition;
|
|
13
|
+
static fromLiteral(literal: AbilityConditionLiteralType): AbilityCondition;
|
|
14
|
+
get literal(): AbilityConditionLiteralType;
|
|
12
15
|
}
|
|
13
16
|
export default AbilityCondition;
|
package/dist/AbilityError.d.ts
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import AbilityRule from './AbilityRule';
|
|
2
|
+
import AbilityRuleSet from '~/AbilityRuleSet';
|
|
3
|
+
import AbilityPolicy from '~/AbilityPolicy';
|
|
4
|
+
import AbilityMatch from '~/AbilityMatch';
|
|
5
|
+
export type AbilityExplainConfig = {
|
|
6
|
+
readonly type: AbilityExplainType;
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly match: AbilityMatch;
|
|
9
|
+
};
|
|
10
|
+
export declare class AbilityExplain {
|
|
11
|
+
readonly type: AbilityExplainType;
|
|
12
|
+
readonly children: AbilityExplain[];
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly match: AbilityMatch;
|
|
15
|
+
constructor(config: AbilityExplainConfig, children?: AbilityExplain[]);
|
|
16
|
+
toString(indent?: number): string;
|
|
17
|
+
}
|
|
18
|
+
export declare class AbilityExplainRule extends AbilityExplain {
|
|
19
|
+
constructor(rule: AbilityRule);
|
|
20
|
+
}
|
|
21
|
+
export declare class AbilityExplainRuleSet extends AbilityExplain {
|
|
22
|
+
constructor(ruleSet: AbilityRuleSet);
|
|
23
|
+
}
|
|
24
|
+
export declare class AbilityExplainPolicy extends AbilityExplain {
|
|
25
|
+
constructor(policy: AbilityPolicy);
|
|
26
|
+
}
|
|
27
|
+
export type AbilityExplainType = 'policy' | 'rule' | 'ruleSet';
|
package/dist/AbilityMatch.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import AbilityCode from './AbilityCode';
|
|
2
|
-
export type
|
|
3
|
-
export declare class AbilityMatch extends AbilityCode<
|
|
2
|
+
export type AbilityMatchCodeType = 'pending' | 'match' | 'mismatch';
|
|
3
|
+
export declare class AbilityMatch extends AbilityCode<AbilityMatchCodeType> {
|
|
4
4
|
static pending: AbilityMatch;
|
|
5
5
|
static match: AbilityMatch;
|
|
6
6
|
static mismatch: AbilityMatch;
|
package/dist/AbilityParser.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import AbilityPolicy from './AbilityPolicy';
|
|
2
|
+
export type Primitive = string | number | boolean | null | undefined;
|
|
3
|
+
export type NestedDict<T = Primitive> = {
|
|
4
|
+
[key: string]: NestedDict<T> | T;
|
|
5
|
+
};
|
|
2
6
|
export declare class AbilityParser {
|
|
3
7
|
/**
|
|
4
8
|
* Sets a value in a nested object structure based on a dot/bracket notation path.
|
|
@@ -6,13 +10,50 @@ export declare class AbilityParser {
|
|
|
6
10
|
* @param path - The path to the property in dot/bracket notation.
|
|
7
11
|
* @param value - The value to set at the specified path.
|
|
8
12
|
*/
|
|
9
|
-
static setValueDotValue(object:
|
|
13
|
+
static setValueDotValue<T extends Primitive>(object: NestedDict<T>, path: string, value: T): void;
|
|
10
14
|
/**
|
|
11
15
|
* Generates TypeScript type definitions based on the provided policies.
|
|
12
16
|
* @param policies - An array of AbilityPolicy instances.
|
|
13
|
-
* @
|
|
14
|
-
* @returns A record containing the generated type definitions.
|
|
17
|
+
* @returns A generated type definitions.
|
|
15
18
|
*/
|
|
16
|
-
static generateTypeDefs(policies: readonly AbilityPolicy[]
|
|
19
|
+
static generateTypeDefs(policies: readonly AbilityPolicy[]): string;
|
|
20
|
+
/**
|
|
21
|
+
* Determines TypeScript type based on the rule
|
|
22
|
+
* @param rule - The rule to analyze
|
|
23
|
+
* @returns TypeScript type as string
|
|
24
|
+
*/
|
|
25
|
+
private static determineTypeFromRule;
|
|
26
|
+
/**
|
|
27
|
+
* Gets TypeScript type for array values
|
|
28
|
+
* @param resource - The resource value to analyze
|
|
29
|
+
* @returns TypeScript array type as string
|
|
30
|
+
*/
|
|
31
|
+
private static getArrayType;
|
|
32
|
+
/**
|
|
33
|
+
* Gets primitive TypeScript type for a value
|
|
34
|
+
* @param value - The value to analyze
|
|
35
|
+
* @returns TypeScript primitive type as string
|
|
36
|
+
*/
|
|
37
|
+
private static getPrimitiveType;
|
|
38
|
+
/**
|
|
39
|
+
* Builds nested structure from flat paths
|
|
40
|
+
* Example: 'user.profile.name' -> { user: { profile: { name: 'string' } } }
|
|
41
|
+
* @param flatStructure - Flat structure with dot notation paths
|
|
42
|
+
* @returns Nested object structure
|
|
43
|
+
*/
|
|
44
|
+
private static buildNestedStructure;
|
|
45
|
+
/**
|
|
46
|
+
* Formats type structure into a string
|
|
47
|
+
* @param structure - Nested type structure
|
|
48
|
+
* @returns Formatted TypeScript type definition string
|
|
49
|
+
*/
|
|
50
|
+
private static formatTypeDefinitions;
|
|
51
|
+
/**
|
|
52
|
+
* Recursively formats nested object
|
|
53
|
+
* @param obj - Object to format
|
|
54
|
+
* @param indent - Current indentation level
|
|
55
|
+
* @returns Formatted string
|
|
56
|
+
*/
|
|
57
|
+
private static formatNestedObject;
|
|
17
58
|
}
|
|
18
59
|
export default AbilityParser;
|
package/dist/AbilityPolicy.d.ts
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import AbilityRuleSet, { AbilityRuleSetConfig } from './AbilityRuleSet';
|
|
2
2
|
import AbilityMatch from './AbilityMatch';
|
|
3
|
-
import AbilityCompare, {
|
|
4
|
-
import AbilityPolicyEffect, {
|
|
3
|
+
import AbilityCompare, { AbilityCompareCodeType } from './AbilityCompare';
|
|
4
|
+
import AbilityPolicyEffect, { AbilityPolicyEffectCodeType } from './AbilityPolicyEffect';
|
|
5
|
+
import { AbilityExplain } from '~/AbilityExplain';
|
|
5
6
|
export type AbilityPolicyConfig = {
|
|
6
7
|
readonly action: string;
|
|
7
|
-
readonly effect:
|
|
8
|
-
readonly compareMethod:
|
|
9
|
-
readonly ruleSet: AbilityRuleSetConfig[];
|
|
8
|
+
readonly effect: AbilityPolicyEffectCodeType;
|
|
9
|
+
readonly compareMethod: AbilityCompareCodeType;
|
|
10
|
+
readonly ruleSet: readonly AbilityRuleSetConfig[];
|
|
10
11
|
readonly id: string;
|
|
11
12
|
readonly name: string;
|
|
12
13
|
};
|
|
14
|
+
export type AbilityPolicyConstructorProps = {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
action: string;
|
|
18
|
+
effect: AbilityPolicyEffect;
|
|
19
|
+
compareMethod?: AbilityCompare;
|
|
20
|
+
};
|
|
13
21
|
export declare class AbilityPolicy<Resources extends object = object> {
|
|
14
22
|
matchState: AbilityMatch;
|
|
15
23
|
/**
|
|
@@ -36,15 +44,11 @@ export declare class AbilityPolicy<Resources extends object = object> {
|
|
|
36
44
|
*/
|
|
37
45
|
id: string;
|
|
38
46
|
/**
|
|
39
|
-
*
|
|
47
|
+
* Running the `enforce` or `resolve` method
|
|
48
|
+
* will select only those from all passed policies that fall under the specified action.
|
|
40
49
|
*/
|
|
41
50
|
action: string;
|
|
42
|
-
constructor(params:
|
|
43
|
-
id: string;
|
|
44
|
-
name: string;
|
|
45
|
-
action: string;
|
|
46
|
-
effect: AbilityPolicyEffect;
|
|
47
|
-
});
|
|
51
|
+
constructor(params: AbilityPolicyConstructorProps);
|
|
48
52
|
/**
|
|
49
53
|
* Add rule set to the policy
|
|
50
54
|
* @param ruleSet - The rule set to add
|
|
@@ -55,6 +59,13 @@ export declare class AbilityPolicy<Resources extends object = object> {
|
|
|
55
59
|
* @param resources - The resource to check
|
|
56
60
|
*/
|
|
57
61
|
check(resources: Resources): AbilityMatch;
|
|
62
|
+
explain(): AbilityExplain;
|
|
63
|
+
/**
|
|
64
|
+
* Parses an array of policy configurations into an array of AbilityPolicy instances.
|
|
65
|
+
* @param configs - Array of policy configurations
|
|
66
|
+
* @returns Array of AbilityPolicy instances
|
|
67
|
+
*/
|
|
68
|
+
static parseAll<Resources extends object = object>(configs: readonly AbilityPolicyConfig[]): AbilityPolicy<Resources>[];
|
|
58
69
|
/**
|
|
59
70
|
* Parse the config JSON format to Policy class instance
|
|
60
71
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import AbilityCode from './AbilityCode';
|
|
2
|
-
export type
|
|
3
|
-
export declare class AbilityPolicyEffect extends AbilityCode<
|
|
2
|
+
export type AbilityPolicyEffectCodeType = 'deny' | 'permit';
|
|
3
|
+
export declare class AbilityPolicyEffect extends AbilityCode<AbilityPolicyEffectCodeType> {
|
|
4
4
|
static deny: AbilityPolicyEffect;
|
|
5
5
|
static permit: AbilityPolicyEffect;
|
|
6
6
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import AbilityPolicy from './AbilityPolicy';
|
|
2
2
|
import AbilityPolicyEffect from './AbilityPolicyEffect';
|
|
3
|
+
import { AbilityExplain } from '~/AbilityExplain';
|
|
3
4
|
export declare class AbilityResolver<Resources extends object = object> {
|
|
4
5
|
policies: readonly AbilityPolicy<Resources>[];
|
|
5
6
|
constructor(policyOrListOfPolicies: readonly AbilityPolicy<Resources>[] | AbilityPolicy<Resources>);
|
|
@@ -10,6 +11,7 @@ export declare class AbilityResolver<Resources extends object = object> {
|
|
|
10
11
|
* @param resource - Resource
|
|
11
12
|
*/
|
|
12
13
|
resolve<Action extends keyof Resources>(action: Action, resource: Resources[Action]): this;
|
|
14
|
+
resolveWithExplain<Action extends keyof Resources>(action: Action, resource: Resources[Action]): readonly AbilityExplain[];
|
|
13
15
|
enforce<Action extends keyof Resources>(action: Action, resource: Resources[Action]): void | never;
|
|
14
16
|
/**
|
|
15
17
|
* Get the last effect of the policy
|
package/dist/AbilityRule.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import AbilityMatch from './AbilityMatch';
|
|
2
|
-
import AbilityCondition, {
|
|
2
|
+
import AbilityCondition, { AbilityConditionCodeType } from './AbilityCondition';
|
|
3
3
|
export type AbilityRuleConfig = {
|
|
4
|
-
readonly id
|
|
5
|
-
readonly name
|
|
4
|
+
readonly id?: string | null;
|
|
5
|
+
readonly name?: string | null;
|
|
6
6
|
/**
|
|
7
7
|
* Subject key path like a 'user.name'
|
|
8
8
|
*/
|
|
@@ -11,8 +11,14 @@ export type AbilityRuleConfig = {
|
|
|
11
11
|
* Resource key path like a 'user.name' or value
|
|
12
12
|
*/
|
|
13
13
|
readonly resource: string | number | boolean | (string | number)[];
|
|
14
|
-
readonly condition:
|
|
14
|
+
readonly condition: AbilityConditionCodeType;
|
|
15
15
|
};
|
|
16
|
+
export type AbilityRuleConstructorProps = Omit<AbilityRuleConfig, 'condition'> & {
|
|
17
|
+
readonly condition: AbilityCondition;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Represents a rule that defines a condition to be checked against a subject and resource.
|
|
21
|
+
*/
|
|
16
22
|
export declare class AbilityRule<Resources extends object = object> {
|
|
17
23
|
/**
|
|
18
24
|
* Subject key path like a 'user.name'
|
|
@@ -26,7 +32,16 @@ export declare class AbilityRule<Resources extends object = object> {
|
|
|
26
32
|
name: string;
|
|
27
33
|
id: string;
|
|
28
34
|
state: AbilityMatch;
|
|
29
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Creates an instance of AbilityRule.
|
|
37
|
+
* @param {string} options.id - The unique identifier of the rule.
|
|
38
|
+
* @param {string} options.name - The name of the rule.
|
|
39
|
+
* @param {AbilityCondition} options.condition - The condition to evaluate.
|
|
40
|
+
* @param {string} options.subject - The subject of the rule.
|
|
41
|
+
* @param {string} options.resource - The resource to compare against.
|
|
42
|
+
* @param params
|
|
43
|
+
*/
|
|
44
|
+
constructor(params: AbilityRuleConstructorProps);
|
|
30
45
|
/**
|
|
31
46
|
* Check if the rule is matched
|
|
32
47
|
* @param resource - The resource to check
|
|
@@ -51,5 +66,13 @@ export declare class AbilityRule<Resources extends object = object> {
|
|
|
51
66
|
* Export the rule to config object
|
|
52
67
|
*/
|
|
53
68
|
export(): AbilityRuleConfig;
|
|
69
|
+
static equal<Resources extends object = object>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources>;
|
|
70
|
+
static notIn<Resources extends object = object>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources>;
|
|
71
|
+
static in<Resources extends object = object>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources>;
|
|
72
|
+
static notEqual<Resources extends object = object>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources>;
|
|
73
|
+
static lessThan<Resources extends object = object>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources>;
|
|
74
|
+
static lessOrEqual<Resources extends object = object>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources>;
|
|
75
|
+
static moreThan<Resources extends object = object>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources>;
|
|
76
|
+
static moreOrEqual<Resources extends object = object>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources>;
|
|
54
77
|
}
|
|
55
78
|
export default AbilityRule;
|
package/dist/AbilityRuleSet.d.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import AbilityRule, { AbilityRuleConfig } from './AbilityRule';
|
|
2
|
-
import AbilityCompare, {
|
|
2
|
+
import AbilityCompare, { AbilityCompareCodeType } from './AbilityCompare';
|
|
3
3
|
import AbilityMatch from './AbilityMatch';
|
|
4
4
|
export type AbilityRuleSetConfig = {
|
|
5
|
-
readonly id
|
|
6
|
-
readonly name
|
|
7
|
-
readonly compareMethod:
|
|
8
|
-
readonly rules: AbilityRuleConfig[];
|
|
5
|
+
readonly id?: string | null;
|
|
6
|
+
readonly name?: string | null;
|
|
7
|
+
readonly compareMethod: AbilityCompareCodeType;
|
|
8
|
+
readonly rules: readonly AbilityRuleConfig[];
|
|
9
|
+
};
|
|
10
|
+
export type AbilityRuleSetConstructorProps = {
|
|
11
|
+
readonly id?: string | null;
|
|
12
|
+
readonly name?: string | null;
|
|
13
|
+
readonly compareMethod: AbilityCompare;
|
|
9
14
|
};
|
|
10
15
|
export declare class AbilityRuleSet<Resources extends object = object> {
|
|
11
16
|
state: AbilityMatch;
|
|
@@ -28,14 +33,16 @@ export declare class AbilityRuleSet<Resources extends object = object> {
|
|
|
28
33
|
* Group ID
|
|
29
34
|
*/
|
|
30
35
|
id: string;
|
|
31
|
-
constructor(params:
|
|
32
|
-
addRule(rule: AbilityRule
|
|
33
|
-
addRules(rules: AbilityRule[]
|
|
36
|
+
constructor(params: AbilityRuleSetConstructorProps);
|
|
37
|
+
addRule(rule: AbilityRule): this;
|
|
38
|
+
addRules(rules: AbilityRule[]): this;
|
|
34
39
|
check(resources: Resources | null): AbilityMatch;
|
|
35
40
|
/**
|
|
36
41
|
* Parse the config JSON format to Group class instance
|
|
37
42
|
*/
|
|
38
43
|
static parse<Resource extends object = object>(config: AbilityRuleSetConfig): AbilityRuleSet<Resource>;
|
|
39
44
|
export(): AbilityRuleSetConfig;
|
|
45
|
+
static and(rules: AbilityRule[]): AbilityRuleSet<object>;
|
|
46
|
+
static or(rules: AbilityRule[]): AbilityRuleSet<object>;
|
|
40
47
|
}
|
|
41
48
|
export default AbilityRuleSet;
|
package/dist/index.d.ts
CHANGED