@react-protected/core 0.2.0-beta.2 → 0.3.0
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 +36 -0
- package/README.md +9 -41
- package/dist/createGuard.d.ts +9 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +9 -9
- package/dist/types.d.ts +51 -1
- package/package.json +3 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# @react-protected/core
|
|
2
|
+
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- cb262d3: loader, action and middleware support
|
|
8
|
+
|
|
9
|
+
## 0.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 05cda4d: Update roadmap and docs
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 4b835f6: Docs added
|
|
18
|
+
- 11a6537: Configure Changesets-based release automation and public package publish metadata.
|
|
19
|
+
|
|
20
|
+
## 0.2.0-beta.2
|
|
21
|
+
|
|
22
|
+
### Minor Changes
|
|
23
|
+
|
|
24
|
+
- 05cda4d: Update roadmap and docs
|
|
25
|
+
|
|
26
|
+
## 0.1.1-beta.1
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- 4b835f6: Docs added
|
|
31
|
+
|
|
32
|
+
## 0.1.1-beta.0
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- 11a6537: Configure Changesets-based release automation and public package publish metadata.
|
package/README.md
CHANGED
|
@@ -1,22 +1,6 @@
|
|
|
1
1
|
# @react-protected/core
|
|
2
2
|
|
|
3
|
-
Framework-agnostic access-control logic. No dependency on React, a router, or
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Installation
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install @react-protected/core
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
yarn add @react-protected/core
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
pnpm add @react-protected/core
|
|
19
|
-
```
|
|
3
|
+
Framework-agnostic access-control logic. No dependency on React, a router, or redirect policy.
|
|
20
4
|
|
|
21
5
|
## Usage
|
|
22
6
|
|
|
@@ -27,36 +11,20 @@ const guard = createGuard({
|
|
|
27
11
|
getUser: () => store.getState().user,
|
|
28
12
|
hasRole: (user, roles) => roles.some((role) => user.roles.includes(role)),
|
|
29
13
|
hasPermission: (user, permissions) =>
|
|
30
|
-
permissions.every((
|
|
14
|
+
permissions.every((permission) => user.permissions.includes(permission)),
|
|
31
15
|
})
|
|
32
16
|
|
|
33
17
|
const result = guard.check({ access: 'authenticated', roles: ['admin'] })
|
|
34
18
|
|
|
35
|
-
if (result.allowed) {
|
|
36
|
-
//
|
|
37
|
-
} else {
|
|
38
|
-
// result.reason: 'unauthenticated' | 'forbidden'
|
|
19
|
+
if (!result.allowed) {
|
|
20
|
+
// result.reason: 'unauthenticated' | 'authenticated' | 'forbidden'
|
|
39
21
|
}
|
|
40
22
|
```
|
|
41
23
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
When `roles` or `permissions` are set without an explicit `access` field, the route is treated as `'authenticated'` automatically:
|
|
45
|
-
|
|
46
|
-
```ts
|
|
47
|
-
guard.check({ roles: ['admin'] })
|
|
48
|
-
// equivalent to: guard.check({ access: 'authenticated', roles: ['admin'] })
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Packages
|
|
52
|
-
|
|
53
|
-
| Package | Description |
|
|
54
|
-
| --- | --- |
|
|
55
|
-
| `@react-protected/core` | This package — pure access-control logic |
|
|
56
|
-
| `@react-protected/react` | React context, hooks, and `HasAccess` component |
|
|
57
|
-
| `@react-protected/react-router` | Adapter for React Router |
|
|
24
|
+
Supported access levels:
|
|
58
25
|
|
|
59
|
-
|
|
26
|
+
- `'public'`
|
|
27
|
+
- `'authenticated'`
|
|
28
|
+
- `'unauthenticated'`
|
|
60
29
|
|
|
61
|
-
|
|
62
|
-
- [Examples](https://github.com/astakhovaskold/react-protected/blob/main/docs/en/README.md)
|
|
30
|
+
When `roles` or `permissions` are set without `access`, the guard treats the config as authenticated-only.
|
package/dist/createGuard.d.ts
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
1
|
import { Guard, GuardOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a guard that evaluates access against the current user.
|
|
4
|
+
*
|
|
5
|
+
* @typeParam TUser - User shape returned by `getUser`.
|
|
6
|
+
* @param options - Access callbacks and user accessors used by the guard.
|
|
7
|
+
* @returns A reusable guard with resolved defaults for authentication, role, and permission checks.
|
|
8
|
+
* @remarks When `roles` or `permissions` are provided without `access`, the guard treats the config
|
|
9
|
+
* as authenticated-only.
|
|
10
|
+
*/
|
|
2
11
|
export declare function createGuard<TUser = unknown>(options: GuardOptions<TUser>): Guard<TUser>;
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function c(a){const s={getUser:a.getUser,isAuthenticated:a.isAuthenticated??(e=>e!==null),hasRole:a.hasRole??(()=>!1),hasPermission:a.hasPermission??(()=>!1)};return{check:e=>{var n,o,i,u;const t=s.getUser(),r=s.isAuthenticated(t),l=e.access??"public",d=l==="authenticated"||!!((n=e.roles)!=null&&n.length)||!!((o=e.permissions)!=null&&o.length);return l==="unauthenticated"?r?{allowed:!1,reason:"authenticated"}:{allowed:!0}:d&&!r?{allowed:!1,reason:"unauthenticated"}:(i=e.roles)!=null&&i.length&&t&&!s.hasRole(t,e.roles)?{allowed:!1,reason:"forbidden"}:(u=e.permissions)!=null&&u.length&&t&&!s.hasPermission(t,e.permissions)?{allowed:!1,reason:"forbidden"}:{allowed:!0}},options:s}}exports.createGuard=c;
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
function
|
|
1
|
+
function c(a) {
|
|
2
2
|
const s = {
|
|
3
|
-
getUser:
|
|
4
|
-
isAuthenticated:
|
|
5
|
-
hasRole:
|
|
6
|
-
hasPermission:
|
|
3
|
+
getUser: a.getUser,
|
|
4
|
+
isAuthenticated: a.isAuthenticated ?? ((e) => e !== null),
|
|
5
|
+
hasRole: a.hasRole ?? (() => !1),
|
|
6
|
+
hasPermission: a.hasPermission ?? (() => !1)
|
|
7
7
|
};
|
|
8
8
|
return { check: (e) => {
|
|
9
|
-
var
|
|
10
|
-
const t = s.getUser(),
|
|
11
|
-
return
|
|
9
|
+
var l, o, i, u;
|
|
10
|
+
const t = s.getUser(), r = s.isAuthenticated(t), n = e.access ?? "public", h = n === "authenticated" || !!((l = e.roles) != null && l.length) || !!((o = e.permissions) != null && o.length);
|
|
11
|
+
return n === "unauthenticated" ? r ? { allowed: !1, reason: "authenticated" } : { allowed: !0 } : h && !r ? { allowed: !1, reason: "unauthenticated" } : (i = e.roles) != null && i.length && t && !s.hasRole(t, e.roles) ? { allowed: !1, reason: "forbidden" } : (u = e.permissions) != null && u.length && t && !s.hasPermission(t, e.permissions) ? { allowed: !1, reason: "forbidden" } : { allowed: !0 };
|
|
12
12
|
}, options: s };
|
|
13
13
|
}
|
|
14
14
|
export {
|
|
15
|
-
|
|
15
|
+
c as createGuard
|
|
16
16
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,26 +1,76 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Access level handled by the framework-agnostic guard.
|
|
3
|
+
*/
|
|
4
|
+
export type AccessLevel = 'public' | 'authenticated' | 'unauthenticated';
|
|
5
|
+
/**
|
|
6
|
+
* Access requirements consumed by `guard.check()` and adapter components.
|
|
7
|
+
*/
|
|
2
8
|
export type AccessConfig = {
|
|
9
|
+
/**
|
|
10
|
+
* Declares whether access is public, requires an authenticated user, or requires
|
|
11
|
+
* an unauthenticated user.
|
|
12
|
+
* Defaults to `'public'` when omitted.
|
|
13
|
+
*/
|
|
3
14
|
access?: AccessLevel;
|
|
15
|
+
/**
|
|
16
|
+
* Roles that must be satisfied by your `hasRole` callback.
|
|
17
|
+
*/
|
|
4
18
|
roles?: Array<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Permissions that must be satisfied by your `hasPermission` callback.
|
|
21
|
+
*/
|
|
5
22
|
permissions?: Array<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Optional metadata for application-specific access logic.
|
|
25
|
+
*/
|
|
6
26
|
meta?: Record<string, unknown>;
|
|
7
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Result returned by `guard.check()`.
|
|
30
|
+
*/
|
|
8
31
|
export type AccessResult = {
|
|
9
32
|
allowed: true;
|
|
10
33
|
} | {
|
|
11
34
|
allowed: false;
|
|
12
35
|
reason: 'unauthenticated';
|
|
36
|
+
} | {
|
|
37
|
+
allowed: false;
|
|
38
|
+
reason: 'authenticated';
|
|
13
39
|
} | {
|
|
14
40
|
allowed: false;
|
|
15
41
|
reason: 'forbidden';
|
|
16
42
|
};
|
|
43
|
+
/**
|
|
44
|
+
* Callbacks and accessors used to create a guard instance.
|
|
45
|
+
*/
|
|
17
46
|
export type GuardOptions<TUser = unknown> = {
|
|
47
|
+
/**
|
|
48
|
+
* Returns the current user or `null` when no user is available.
|
|
49
|
+
*/
|
|
18
50
|
getUser: () => TUser | null;
|
|
51
|
+
/**
|
|
52
|
+
* Overrides the default authenticated check of `user !== null`.
|
|
53
|
+
*/
|
|
19
54
|
isAuthenticated?: (user: TUser | null) => boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Determines whether the current user satisfies the requested roles.
|
|
57
|
+
*/
|
|
20
58
|
hasRole?: (user: TUser, roles: Array<string>) => boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Determines whether the current user satisfies the requested permissions.
|
|
61
|
+
*/
|
|
21
62
|
hasPermission?: (user: TUser, permissions: Array<string>) => boolean;
|
|
22
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* Guard instance returned by `createGuard()`.
|
|
66
|
+
*/
|
|
23
67
|
export type Guard<TUser = unknown> = {
|
|
68
|
+
/**
|
|
69
|
+
* Evaluates whether the current user satisfies the provided access config.
|
|
70
|
+
*/
|
|
24
71
|
check: (config: AccessConfig) => AccessResult;
|
|
72
|
+
/**
|
|
73
|
+
* Resolved guard callbacks with built-in defaults applied.
|
|
74
|
+
*/
|
|
25
75
|
options: Required<GuardOptions<TUser>>;
|
|
26
76
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-protected/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Framework-agnostic route protection logic",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
25
|
-
"dist"
|
|
25
|
+
"dist",
|
|
26
|
+
"CHANGELOG.md"
|
|
26
27
|
],
|
|
27
28
|
"devDependencies": {
|
|
28
29
|
"vite": "^5.0.0",
|