@cedarjs/router 8.0.0-canary.3569 → 8.0.0-canary.3570
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/dist/AuthenticatedRoute.d.ts +1 -1
- package/dist/AuthenticatedRoute.d.ts.map +1 -1
- package/dist/AuthenticatedRoute.js +12 -12
- package/dist/Set.d.ts +18 -26
- package/dist/Set.d.ts.map +1 -1
- package/dist/analyzeRoutes.d.ts +1 -1
- package/dist/analyzeRoutes.d.ts.map +1 -1
- package/dist/analyzeRoutes.js +2 -2
- package/dist/router-context.d.ts +4 -4
- package/dist/router-context.d.ts.map +1 -1
- package/dist/router.d.ts +2 -3
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +1 -1
- package/dist/rsc/ClientRouter.js +0 -5
- package/dist/rsc/ServerRouter.js +8 -6
- package/package.json +6 -6
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
interface AuthenticatedRouteProps {
|
|
3
3
|
children: React.ReactNode;
|
|
4
4
|
roles?: string | string[];
|
|
5
|
-
|
|
5
|
+
permission?: string;
|
|
6
6
|
unauthenticated: string;
|
|
7
7
|
unauthorized?: string;
|
|
8
8
|
whileLoadingAuth?: () => React.ReactElement | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthenticatedRoute.d.ts","sourceRoot":"","sources":["../src/AuthenticatedRoute.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAA;AAQxD,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACzB,
|
|
1
|
+
{"version":3,"file":"AuthenticatedRoute.d.ts","sourceRoot":"","sources":["../src/AuthenticatedRoute.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAA;AAQxD,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,CAAC,EAAE,MAAM,KAAK,CAAC,YAAY,GAAG,IAAI,CAAA;CACnD;AA6ED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA2IhE,CAAA"}
|
|
@@ -45,7 +45,7 @@ const AuthenticatedRoute = ({
|
|
|
45
45
|
unauthenticated,
|
|
46
46
|
unauthorized,
|
|
47
47
|
roles,
|
|
48
|
-
|
|
48
|
+
permission,
|
|
49
49
|
whileLoadingAuth,
|
|
50
50
|
children
|
|
51
51
|
}) => {
|
|
@@ -54,34 +54,34 @@ const AuthenticatedRoute = ({
|
|
|
54
54
|
const {
|
|
55
55
|
loading: authLoading,
|
|
56
56
|
isAuthenticated,
|
|
57
|
-
hasRole
|
|
57
|
+
hasRole,
|
|
58
|
+
hasPermission
|
|
58
59
|
} = routerState.useAuth();
|
|
59
60
|
const { pathname } = useLocation();
|
|
60
61
|
const pathParams = currentPathParams(routerState, pathname);
|
|
61
62
|
const { tenancy } = routerState;
|
|
62
63
|
const useOrg = tenancy?.useOrg ?? useNoOrg;
|
|
63
64
|
const org = useOrg(routerState.useAuth, pathParams);
|
|
64
|
-
const needsOrg =
|
|
65
|
+
const needsOrg = permission !== void 0 && !!tenancy;
|
|
65
66
|
if (needsOrg && !org) {
|
|
66
|
-
if (!tenancy) {
|
|
67
|
-
throw new Error(
|
|
68
|
-
"A PrivateSet with `orgPermission` needs `tenancy` on the Router to find the organization with. Please pass `tenancy` from `@cedarjs/tenancy/web`: <Router useAuth={useAuth} tenancy={tenancy}>"
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
67
|
if (authLoading) {
|
|
72
68
|
return whileLoadingAuth?.() || null;
|
|
73
69
|
}
|
|
74
70
|
if (pathParams["orgSlug"] === void 0) {
|
|
75
71
|
throw new Error(
|
|
76
|
-
"A PrivateSet with `
|
|
72
|
+
"A PrivateSet with `permission` needs an organization to check it in, and the route has no `orgSlug` param. Please only use `permission` on routes with `{orgSlug}` in their path, or pass `createTenancy` a `useOrg` that finds the organization another way"
|
|
77
73
|
);
|
|
78
74
|
}
|
|
79
75
|
throw new Error(
|
|
80
|
-
"A PrivateSet with `
|
|
76
|
+
"A PrivateSet with `permission` got no organization from the Router's `tenancy` for this route, so there is nothing to check it in"
|
|
81
77
|
);
|
|
82
78
|
}
|
|
79
|
+
const auth = {
|
|
80
|
+
hasPermission
|
|
81
|
+
};
|
|
83
82
|
const hasRequiredRoles = !roles || hasRole(roles);
|
|
84
|
-
|
|
83
|
+
const hasRequiredPermission = !!tenancy || permission === void 0 || auth.hasPermission(permission);
|
|
84
|
+
if (isAuthenticated && hasRequiredRoles && hasRequiredPermission) {
|
|
85
85
|
if (!tenancy || !org) {
|
|
86
86
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
|
87
87
|
}
|
|
@@ -92,7 +92,7 @@ const AuthenticatedRoute = ({
|
|
|
92
92
|
}
|
|
93
93
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, tenancy.notAMember ?? null);
|
|
94
94
|
}
|
|
95
|
-
const hasRequiredOrgAccess =
|
|
95
|
+
const hasRequiredOrgAccess = permission === void 0 || (membership.permissions?.includes(permission) ?? false);
|
|
96
96
|
if (hasRequiredOrgAccess) {
|
|
97
97
|
if (mountedOrgId === membership.organizationId) {
|
|
98
98
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
package/dist/Set.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ComponentType, ReactElement, ReactNode } from 'react';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import type {
|
|
3
|
+
import type { PermissionName } from '@cedarjs/auth' with {
|
|
4
4
|
'resolution-mode': 'import'
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
@@ -25,34 +25,26 @@ export interface WrapperProps {
|
|
|
25
25
|
* <Set wrap={PostsScaffoldLayout}>
|
|
26
26
|
*/
|
|
27
27
|
export type WrapperType = ComponentType<WrapperProps>;
|
|
28
|
-
|
|
29
|
-
* `orgPermission`, only in an app with tenancy (see `AuthTenancy`)
|
|
30
|
-
*/
|
|
31
|
-
type SetOrgPermission = AuthTenancy extends {
|
|
32
|
-
enabled: true;
|
|
33
|
-
} ? {
|
|
34
|
-
/**
|
|
35
|
-
* Route is permitted when authenticated and the user's membership in
|
|
36
|
-
* the current organization has this permission (see
|
|
37
|
-
* `createPermissions` in `@cedarjs/tenancy`). With `roles` as well,
|
|
38
|
-
* they need both.
|
|
39
|
-
*
|
|
40
|
-
* The organization is the one the Router's `tenancy` finds for the
|
|
41
|
-
* route, by default the one with the route's `orgSlug` param:
|
|
42
|
-
*
|
|
43
|
-
* <Router useAuth={useAuth} tenancy={tenancy}>
|
|
44
|
-
*
|
|
45
|
-
* A `PrivateSet` with `orgPermission` throws without `tenancy` on the
|
|
46
|
-
* router, or on a route that isn't in an organization.
|
|
47
|
-
*/
|
|
48
|
-
orgPermission?: PermissionName;
|
|
49
|
-
} : Record<never, never>;
|
|
50
|
-
interface SetProps extends SetOrgPermission {
|
|
28
|
+
interface SetProps {
|
|
51
29
|
/**
|
|
52
30
|
* Route is permitted when authenticated and user has any of the provided
|
|
53
31
|
* roles such as "admin" or ["admin", "editor"], in `currentUser.roles`
|
|
54
32
|
*/
|
|
55
33
|
roles?: string | string[];
|
|
34
|
+
/**
|
|
35
|
+
* Route is permitted when authenticated and the user has this permission
|
|
36
|
+
* (see `cedar setup permissions`). With `roles` as well, they need both.
|
|
37
|
+
*
|
|
38
|
+
* Without tenancy, it's one of the user's own permissions, in
|
|
39
|
+
* `currentUser.permissions`.
|
|
40
|
+
*
|
|
41
|
+
* With `tenancy` on the Router, it's a permission of the user's membership
|
|
42
|
+
* in the route's organization: the one the Router's `tenancy` finds, by
|
|
43
|
+
* default the one with the route's `orgSlug` param. A signed-in user who
|
|
44
|
+
* isn't a member gets the tenancy's `notAMember`. A `PrivateSet` with
|
|
45
|
+
* `permission` throws on a route that isn't in an organization.
|
|
46
|
+
*/
|
|
47
|
+
permission?: PermissionName;
|
|
56
48
|
/**
|
|
57
49
|
* Components to wrap all routes in this set with, like layouts. The first
|
|
58
50
|
* one in an array is the outermost one.
|
|
@@ -106,8 +98,8 @@ type PrivateSetProps = Omit<SetProps, 'private' | 'unauthenticated' | 'unauthori
|
|
|
106
98
|
unauthenticated: string;
|
|
107
99
|
/**
|
|
108
100
|
* The page name where a user will be redirected when authenticated but
|
|
109
|
-
* without the required roles. Without it, they're
|
|
110
|
-
* `unauthenticated`.
|
|
101
|
+
* without the required roles or permission. Without it, they're
|
|
102
|
+
* redirected to `unauthenticated`.
|
|
111
103
|
*/
|
|
112
104
|
unauthorized?: string;
|
|
113
105
|
};
|
package/dist/Set.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Set.d.ts","sourceRoot":"","sources":["../src/Set.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACnE,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"Set.d.ts","sourceRoot":"","sources":["../src/Set.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACnE,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;IAClD,iBAAiB,EAAE,QAAQ;CAC5B,CAAA;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC,YAAY,CAAC,CAAA;AAErD,UAAU,QAAQ;IAChB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACzB;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,cAAc,CAAA;IAC3B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,WAAW,EAAE,CAAA;IAC3C;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,qCAAqC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,QAAQ,EAAE,SAAS,CAAA;IACnB,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,MAAM,YAAY,GAAG,IAAI,CAAA;IAC5C,gBAAgB,CAAC,EAAE,MAAM,YAAY,GAAG,IAAI,CAAA;CAC7C;AAED;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,QAAQ,qBAIlC;AAED,KAAK,eAAe,GAAG,IAAI,CACzB,QAAQ,EACR,SAAS,GAAG,iBAAiB,GAAG,cAAc,CAC/C,GAAG;IACF;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,oDAAoD;AACpD,wBAAgB,OAAO,CAAC,KAAK,EAAE,eAAe,qBAI7C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,qBAIhD;AAED,eAAO,MAAM,SAAS,GAAI,MAAM,SAAS,KAAG,IAAI,IAAI,YAAY,CAAC,QAAQ,CAOxE,CAAA;AAED,eAAO,MAAM,gBAAgB,GAC3B,MAAM,SAAS,KACd,IAAI,IAAI,YAAY,CAAC,eAAe,CAEtC,CAAA;AAGD,eAAO,MAAM,aAAa,GACxB,MAAM,SAAS,KACd,IAAI,IAAI,YAAY,CAAC,eAAe,CAEtC,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,SAAS,aAKpB"}
|
package/dist/analyzeRoutes.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzeRoutes.d.ts","sourceRoot":"","sources":["../src/analyzeRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAQzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,WAAW,CAAA;AAElB,KAAK,gBAAgB,GAAG,MAAM,YAAY,GAAG,IAAI,CAAA;AAIjD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,CACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,KACtD,MAAM,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,SAAS,WAAW,EAAE,CAAA;AAE7C;;;GAGG;AACH,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"analyzeRoutes.d.ts","sourceRoot":"","sources":["../src/analyzeRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAQzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,WAAW,CAAA;AAElB,KAAK,gBAAgB,GAAG,MAAM,YAAY,GAAG,IAAI,CAAA;AAIjD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,CACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,KACtD,MAAM,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,SAAS,WAAW,EAAE,CAAA;AAE7C;;;GAGG;AACH,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,YAAY,GAAG,IAAI,CAAA;CAC7C;AAED,UAAU,GAAG;IACX,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,QAAQ,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,cAAc,CAAA;CACtB;AA+CD,KAAK,SAAS,GAAG,MAAM,CAAA;AAEvB;;;;GAIG;AACH,UAAU,aAAa;IACrB,IAAI,EAAE,SAAS,CAAA;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAA;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,IAAI,EAAE,GAAG,EAAE,CAAA;CACZ;AAED,UAAU,oBAAoB;IAC5B,eAAe,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CAC3C;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,SAAS,EACnB,EAAE,eAAe,EAAE,cAAc,EAAE,EAAE,oBAAoB;;;;;;EAqK1D"}
|
package/dist/analyzeRoutes.js
CHANGED
|
@@ -25,8 +25,8 @@ function pickSetRenderProps(props) {
|
|
|
25
25
|
if (props.roles !== void 0) {
|
|
26
26
|
picked.roles = props.roles;
|
|
27
27
|
}
|
|
28
|
-
if (props.
|
|
29
|
-
picked.
|
|
28
|
+
if (props.permission !== void 0) {
|
|
29
|
+
picked.permission = props.permission;
|
|
30
30
|
}
|
|
31
31
|
if (props.whileLoadingAuth !== void 0) {
|
|
32
32
|
picked.whileLoadingAuth = props.whileLoadingAuth;
|
package/dist/router-context.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export interface RouterMembership {
|
|
|
15
15
|
organizationId: string;
|
|
16
16
|
/** The user's role in the organization, passed on to the `OrgProvider` */
|
|
17
17
|
role: string;
|
|
18
|
-
/** What the membership may do, for `<PrivateSet
|
|
18
|
+
/** What the membership may do, for `<PrivateSet permission>` */
|
|
19
19
|
permissions?: readonly string[] | undefined;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
@@ -35,9 +35,9 @@ export interface RouterOrg {
|
|
|
35
35
|
*
|
|
36
36
|
* One of the app's own can answer in three ways:
|
|
37
37
|
* - an organization, with the user's membership in it or `null` for none.
|
|
38
|
-
* A set with `
|
|
38
|
+
* A set with `permission` denies a user with no
|
|
39
39
|
* membership, and the router renders the tenancy's `notAMember`.
|
|
40
|
-
* - `null`, for no organization: a set with `
|
|
40
|
+
* - `null`, for no organization: a set with `permission` then
|
|
41
41
|
* throws the router's own error.
|
|
42
42
|
* - throw an error of its own, such as for an organization that's been
|
|
43
43
|
* suspended. It reaches the app's error boundary like any error thrown
|
|
@@ -55,7 +55,7 @@ export interface OrgProviderProps {
|
|
|
55
55
|
* How the router handles organizations. `createTenancy` from
|
|
56
56
|
* `@cedarjs/tenancy/web` makes one. The router renders its `OrgProvider`
|
|
57
57
|
* around the layouts and page of a `PrivateSet` whose route is in an
|
|
58
|
-
* organization, and checks `
|
|
58
|
+
* organization, and checks a set's `permission` against the
|
|
59
59
|
* membership its `useOrg` finds.
|
|
60
60
|
*/
|
|
61
61
|
export interface Tenancy {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-context.d.ts","sourceRoot":"","sources":["../src/router-context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAA;AAEjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;IACxD,iBAAiB,EAAE,QAAQ;CAC5B,CAAA;AAGD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,MAAM,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAC9C,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,CACR,CAAA;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,cAAc,EAAE,MAAM,CAAA;IACtB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAA;IACZ,
|
|
1
|
+
{"version":3,"file":"router-context.d.ts","sourceRoot":"","sources":["../src/router-context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAA;AAEjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;IACxD,iBAAiB,EAAE,QAAQ;CAC5B,CAAA;AAGD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,MAAM,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAC9C,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,CACR,CAAA;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,cAAc,EAAE,MAAM,CAAA;IACtB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAA;IACZ,gEAAgE;IAChE,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;CAC5C;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACnC,WAAW,EAAE,SAAS,gBAAgB,EAAE,CAAA;CACzC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,MAAM,GAAG,CACnB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC3B,SAAS,GAAG,IAAI,CAAA;AAErB,sDAAsD;AACtD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,WAAW,EAAE,SAAS,gBAAgB,EAAE,CAAA;IACxC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,WAAW,EAAE,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAA;IAClD,mFAAmF;IACnF,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACtC,OAAO,EAAE,OAAO,CAAA;IAChB,sDAAsD;IACtD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;CAC5C;AAID,MAAM,WAAW,0BAA2B,SAAQ,IAAI,CACtD,WAAW,EACX,SAAS,CACV;IACC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;IAC3C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAwBtE,CAAA;AAED,eAAO,MAAM,cAAc,mBAU1B,CAAA"}
|
package/dist/router.d.ts
CHANGED
|
@@ -6,15 +6,14 @@ import type { AuthTenancy } from '@cedarjs/auth' with {
|
|
|
6
6
|
import type { RouterContextProviderProps, Tenancy } from './router-context.js';
|
|
7
7
|
import type { TrailingSlashesTypes } from './util.js';
|
|
8
8
|
/**
|
|
9
|
-
* `tenancy`, only in an app with tenancy (see `AuthTenancy`)
|
|
10
|
-
* `orgPermission`
|
|
9
|
+
* `tenancy`, only in an app with tenancy (see `AuthTenancy`)
|
|
11
10
|
*/
|
|
12
11
|
type RouterTenancy = AuthTenancy extends {
|
|
13
12
|
enabled: true;
|
|
14
13
|
} ? {
|
|
15
14
|
/**
|
|
16
15
|
* How the router handles organizations: finding the one of the current
|
|
17
|
-
* route, checking `
|
|
16
|
+
* route, checking a set's `permission` in it, and providing
|
|
18
17
|
* it to the layouts and page of a `PrivateSet`. Pass the `tenancy` from
|
|
19
18
|
* `createTenancy` in `@cedarjs/tenancy/web`:
|
|
20
19
|
*
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,OAAO,CAAA;AACpD,OAAO,KAAwB,MAAM,OAAO,CAAA;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;IAC/C,iBAAiB,EAAE,QAAQ;CAC5B,CAAA;AAYD,OAAO,KAAK,EAAE,0BAA0B,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAK9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAErD
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,OAAO,CAAA;AACpD,OAAO,KAAwB,MAAM,OAAO,CAAA;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;IAC/C,iBAAiB,EAAE,QAAQ;CAC5B,CAAA;AAYD,OAAO,KAAK,EAAE,0BAA0B,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAK9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAErD;;GAEG;AACH,KAAK,aAAa,GAAG,WAAW,SAAS;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACtD;IACE;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,GACD,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAExB,MAAM,WAAW,WACf,SACE,IAAI,CAAC,0BAA0B,EAAE,QAAQ,GAAG,iBAAiB,GAAG,SAAS,CAAC,EAC1E,aAAa;IACf,eAAe,CAAC,EAAE,oBAAoB,CAAA;IACtC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAsCD,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAAwB,CAAA"}
|
package/dist/router.js
CHANGED
|
@@ -163,7 +163,7 @@ const WrappedPage = memo(({ sets, children }) => {
|
|
|
163
163
|
unauthenticated,
|
|
164
164
|
unauthorized: set.props.unauthorized,
|
|
165
165
|
roles: set.props.roles,
|
|
166
|
-
|
|
166
|
+
permission: set.props.permission,
|
|
167
167
|
whileLoadingAuth: set.props.whileLoadingAuth
|
|
168
168
|
},
|
|
169
169
|
wrapped
|
package/dist/rsc/ClientRouter.js
CHANGED
|
@@ -33,11 +33,6 @@ const LocationAwareRouter = ({
|
|
|
33
33
|
return /* @__PURE__ */ React.createElement(RscRoutes, { pathname, search });
|
|
34
34
|
}
|
|
35
35
|
const requestedRoute = pathRouteMap[activeRoutePath];
|
|
36
|
-
for (const set of requestedRoute.sets) {
|
|
37
|
-
if (set.props.orgPermission !== void 0) {
|
|
38
|
-
throw new Error("`orgPermission` is not supported with RSC yet");
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
36
|
const reversedSets = requestedRoute.sets.toReversed();
|
|
42
37
|
const privateSet = reversedSets.find((set) => set.isPrivate);
|
|
43
38
|
if (privateSet) {
|
package/dist/rsc/ServerRouter.js
CHANGED
|
@@ -101,16 +101,18 @@ function hasRole(requiredRoles) {
|
|
|
101
101
|
const requiredRolesArray = Array.isArray(requiredRoles) ? requiredRoles : [requiredRoles];
|
|
102
102
|
return requiredRolesArray.some((role) => roles.includes(role));
|
|
103
103
|
}
|
|
104
|
+
function hasPermission(permission) {
|
|
105
|
+
const { currentUser } = getAuthState();
|
|
106
|
+
const permissions = currentUser && typeof currentUser === "object" && "permissions" in currentUser ? currentUser.permissions : void 0;
|
|
107
|
+
return Array.isArray(permissions) && permissions.includes(permission);
|
|
108
|
+
}
|
|
104
109
|
const AuthenticatedRoute = ({
|
|
105
110
|
children,
|
|
106
111
|
roles,
|
|
107
|
-
|
|
112
|
+
permission
|
|
108
113
|
}) => {
|
|
109
114
|
const { isAuthenticated } = getAuthState();
|
|
110
|
-
|
|
111
|
-
throw new Error("`orgPermission` is not supported with RSC yet");
|
|
112
|
-
}
|
|
113
|
-
const isAuthorized = isAuthenticated && (!roles || hasRole(roles));
|
|
115
|
+
const isAuthorized = isAuthenticated && (!roles || hasRole(roles)) && (permission === void 0 || hasPermission(permission));
|
|
114
116
|
if (isAuthorized) {
|
|
115
117
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
|
116
118
|
}
|
|
@@ -137,7 +139,7 @@ const WrappedPage = ({ routeLoaderElement, sets }) => {
|
|
|
137
139
|
{
|
|
138
140
|
unauthenticated,
|
|
139
141
|
roles: set.props.roles,
|
|
140
|
-
|
|
142
|
+
permission: set.props.permission,
|
|
141
143
|
whileLoadingAuth: set.props.whileLoadingAuth
|
|
142
144
|
},
|
|
143
145
|
wrapped
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/router",
|
|
3
|
-
"version": "8.0.0-canary.
|
|
3
|
+
"version": "8.0.0-canary.3570",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/cedarjs/cedar.git",
|
|
@@ -52,15 +52,15 @@
|
|
|
52
52
|
"test:watch": "vitest watch"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@cedarjs/project-config": "8.0.0-canary.
|
|
56
|
-
"@cedarjs/server-store": "8.0.0-canary.
|
|
55
|
+
"@cedarjs/project-config": "8.0.0-canary.3570",
|
|
56
|
+
"@cedarjs/server-store": "8.0.0-canary.3570",
|
|
57
57
|
"react-server-dom-webpack": "19.3.1",
|
|
58
58
|
"ts-toolbelt": "9.6.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@arethetypeswrong/cli": "0.18.5",
|
|
62
|
-
"@cedarjs/auth": "8.0.0-canary.
|
|
63
|
-
"@cedarjs/framework-tools": "8.0.0-canary.
|
|
62
|
+
"@cedarjs/auth": "8.0.0-canary.3570",
|
|
63
|
+
"@cedarjs/framework-tools": "8.0.0-canary.3570",
|
|
64
64
|
"@testing-library/jest-dom": "6.9.1",
|
|
65
65
|
"@types/react": "^19.2.0",
|
|
66
66
|
"@types/react-dom": "^19.2.0",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"vitest": "4.1.12"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
|
-
"@cedarjs/auth": "8.0.0-canary.
|
|
77
|
+
"@cedarjs/auth": "8.0.0-canary.3570",
|
|
78
78
|
"react": "19.3.1",
|
|
79
79
|
"react-dom": "19.3.1"
|
|
80
80
|
},
|