@lobb-js/lobb-ext-auth 0.11.1 → 0.11.2
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/index.js +1 -1
- package/{extensions/auth → dist/shared}/permissions.d.ts +1 -1
- package/dist/shared/permissions.js +35 -0
- package/extensions/auth/studio/index.ts +1 -1
- package/extensions/auth/{permissions.ts → studio/shared/permissions.ts} +9 -1
- package/extensions/auth/tests/permissions.test.ts +1 -1
- package/extensions/auth/workflows/utils.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { onStartup, onRouteChange } from "./onStartup";
|
|
|
3
3
|
import LoginPage from "./lib/components/pages/loginPage/index.svelte";
|
|
4
4
|
import UserSettings from "./lib/components/pages/userSettings/index.svelte";
|
|
5
5
|
import Settings from "./lib/components/pages/settings/index.svelte";
|
|
6
|
-
import { isActionAllowed } from "
|
|
6
|
+
import { isActionAllowed } from "./shared/permissions";
|
|
7
7
|
// TODO we should export the extension object directly without a function at all. because we dont set configuration in here
|
|
8
8
|
export default function extension(utils) {
|
|
9
9
|
return {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { CollectionPermissionActionsKeys, PermissionsConfig } from "
|
|
1
|
+
import type { CollectionPermissionActionsKeys, PermissionsConfig } from "../../config/extensionConfigSchema.ts";
|
|
2
2
|
export declare function isActionAllowed(collection: string, action: CollectionPermissionActionsKeys, permissions: PermissionsConfig | undefined): boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Lives under studio/ for packaging reasons — `svelte-package` only bundles
|
|
2
|
+
// files inside its `--input` root, so anything the studio entry imports has
|
|
3
|
+
// to be reachable from there. The backend imports this same file via
|
|
4
|
+
// `../studio/shared/permissions` so there's still one source of truth.
|
|
5
|
+
//
|
|
6
|
+
// Anything in this folder must stay environment-neutral (no DOM, no Node-only
|
|
7
|
+
// APIs, no top-level side effects) so it runs the same way on both sides.
|
|
8
|
+
// Pure permission check shared by the server-side handlePolicy and the
|
|
9
|
+
// studio's auth.canAccess workflow. Walks the permissions tree and returns
|
|
10
|
+
// a yes/no — server-side then layers on guards/filters/error-throwing,
|
|
11
|
+
// client-side uses the answer to decide whether to render UI.
|
|
12
|
+
//
|
|
13
|
+
// An object value for action permission means "conditional access" (filter
|
|
14
|
+
// and/or fields restrictions). For UI gating that counts as allowed; the
|
|
15
|
+
// server enforces the actual restrictions on real requests.
|
|
16
|
+
export function isActionAllowed(collection, action, permissions) {
|
|
17
|
+
if (permissions === true)
|
|
18
|
+
return true;
|
|
19
|
+
if (!permissions)
|
|
20
|
+
return false;
|
|
21
|
+
const collPerm = permissions[collection];
|
|
22
|
+
if (collPerm === true)
|
|
23
|
+
return true;
|
|
24
|
+
if (!collPerm)
|
|
25
|
+
return false;
|
|
26
|
+
const actionPerm = collPerm[action];
|
|
27
|
+
if (actionPerm === true)
|
|
28
|
+
return true;
|
|
29
|
+
// A conditional grant must actually list at least one constraint
|
|
30
|
+
// (filter / fields / payloadGuard / mutate). Empty `{}` collapses back
|
|
31
|
+
// to "no grant" — explicit `true` is required for unconditional access.
|
|
32
|
+
return (typeof actionPerm === "object" &&
|
|
33
|
+
actionPerm !== null &&
|
|
34
|
+
Object.keys(actionPerm).length > 0);
|
|
35
|
+
}
|
|
@@ -4,7 +4,7 @@ import { onStartup, onRouteChange } from "./onStartup";
|
|
|
4
4
|
import LoginPage from "./lib/components/pages/loginPage/index.svelte";
|
|
5
5
|
import UserSettings from "./lib/components/pages/userSettings/index.svelte";
|
|
6
6
|
import Settings from "./lib/components/pages/settings/index.svelte";
|
|
7
|
-
import { isActionAllowed } from "
|
|
7
|
+
import { isActionAllowed } from "./shared/permissions";
|
|
8
8
|
import type { CollectionPermissionActionsKeys } from "../config/extensionConfigSchema";
|
|
9
9
|
|
|
10
10
|
// TODO we should export the extension object directly without a function at all. because we dont set configuration in here
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
// Lives under studio/ for packaging reasons — `svelte-package` only bundles
|
|
2
|
+
// files inside its `--input` root, so anything the studio entry imports has
|
|
3
|
+
// to be reachable from there. The backend imports this same file via
|
|
4
|
+
// `../studio/shared/permissions` so there's still one source of truth.
|
|
5
|
+
//
|
|
6
|
+
// Anything in this folder must stay environment-neutral (no DOM, no Node-only
|
|
7
|
+
// APIs, no top-level side effects) so it runs the same way on both sides.
|
|
8
|
+
|
|
1
9
|
import type {
|
|
2
10
|
CollectionPermissionActionsKeys,
|
|
3
11
|
PermissionsConfig,
|
|
4
|
-
} from "
|
|
12
|
+
} from "../../config/extensionConfigSchema.ts";
|
|
5
13
|
|
|
6
14
|
// Pure permission check shared by the server-side handlePolicy and the
|
|
7
15
|
// studio's auth.canAccess workflow. Walks the permissions tree and returns
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from "bun:test";
|
|
2
|
-
import { isActionAllowed } from "../permissions.ts";
|
|
2
|
+
import { isActionAllowed } from "../studio/shared/permissions.ts";
|
|
3
3
|
|
|
4
4
|
// Default-deny is the contract: only explicit `true` or an object that
|
|
5
5
|
// actually lists at least one constraint counts as a grant. Anything empty
|
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
PermissionsConfig,
|
|
7
7
|
User,
|
|
8
8
|
} from "../config/extensionConfigSchema.ts";
|
|
9
|
-
import { isActionAllowed } from "../permissions.ts";
|
|
9
|
+
import { isActionAllowed } from "../studio/shared/permissions.ts";
|
|
10
10
|
|
|
11
11
|
interface HandlePolicyOutput {
|
|
12
12
|
filter?: Filter;
|