@webiny/app-admin 6.1.0 → 6.2.0-beta.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/base/Admin.js +2 -0
- package/base/Admin.js.map +1 -1
- package/base/Base/DefaultFieldRenderers.d.ts +2 -0
- package/base/Base/DefaultFieldRenderers.js +15 -0
- package/base/Base/DefaultFieldRenderers.js.map +1 -0
- package/base/Base/FieldRenderers/SelectRenderer.d.ts +5 -0
- package/base/Base/FieldRenderers/SelectRenderer.js +24 -0
- package/base/Base/FieldRenderers/SelectRenderer.js.map +1 -0
- package/base/Base/FieldRenderers/TextRenderer.d.ts +5 -0
- package/base/Base/FieldRenderers/TextRenderer.js +21 -0
- package/base/Base/FieldRenderers/TextRenderer.js.map +1 -0
- package/base/Base/Menus.js +7 -0
- package/base/Base/Menus.js.map +1 -1
- package/base/Base.js +2 -1
- package/base/Base.js.map +1 -1
- package/base/createRootContainer.js +2 -0
- package/base/createRootContainer.js.map +1 -1
- package/components/Dialogs/DialogParamsContext.d.ts +6 -0
- package/components/Dialogs/DialogParamsContext.js +11 -0
- package/components/Dialogs/DialogParamsContext.js.map +1 -0
- package/components/Dialogs/DialogsContext.d.ts +2 -0
- package/components/Dialogs/DialogsContext.js +32 -4
- package/components/Dialogs/DialogsContext.js.map +1 -1
- package/components/OptionsMenu/OptionsMenu.d.ts +6 -0
- package/components/OptionsMenu/OptionsMenu.js +3 -3
- package/components/OptionsMenu/OptionsMenu.js.map +1 -1
- package/components/RegisterFeature.js +5 -5
- package/components/RegisterFeature.js.map +1 -1
- package/components/Wcp.d.ts +2 -0
- package/components/Wcp.js +7 -0
- package/components/Wcp.js.map +1 -1
- package/config/AdminConfig/Dialog.d.ts +10 -0
- package/config/AdminConfig/Dialog.js +21 -0
- package/config/AdminConfig/Dialog.js.map +1 -0
- package/config/AdminConfig/FieldRenderer.d.ts +11 -0
- package/config/AdminConfig/FieldRenderer.js +21 -0
- package/config/AdminConfig/FieldRenderer.js.map +1 -0
- package/config/AdminConfig/Form.d.ts +3 -0
- package/config/AdminConfig/Form.js +6 -0
- package/config/AdminConfig/Form.js.map +1 -0
- package/config/AdminConfig.d.ts +10 -0
- package/config/AdminConfig.js +7 -1
- package/config/AdminConfig.js.map +1 -1
- package/exports/admin/security.d.ts +6 -0
- package/exports/admin/security.js +5 -0
- package/exports/admin/security.js.map +1 -1
- package/exports/admin/ui.d.ts +2 -0
- package/exports/admin/ui.js +2 -0
- package/exports/admin/ui.js.map +1 -1
- package/exports/admin.d.ts +0 -3
- package/exports/admin.js +0 -3
- package/exports/admin.js.map +1 -1
- package/features/formModel/Field.d.ts +52 -0
- package/features/formModel/Field.js +201 -0
- package/features/formModel/Field.js.map +1 -0
- package/features/formModel/FieldBuilder.d.ts +45 -0
- package/features/formModel/FieldBuilder.js +158 -0
- package/features/formModel/FieldBuilder.js.map +1 -0
- package/features/formModel/FieldBuilder.test.js +106 -0
- package/features/formModel/FieldBuilder.test.js.map +1 -0
- package/features/formModel/FormModel.d.ts +61 -0
- package/features/formModel/FormModel.js +573 -0
- package/features/formModel/FormModel.js.map +1 -0
- package/features/formModel/FormModel.test.d.ts +1 -0
- package/features/formModel/FormModel.test.js +1140 -0
- package/features/formModel/FormModel.test.js.map +1 -0
- package/features/formModel/FormModelFactory.d.ts +9 -0
- package/features/formModel/FormModelFactory.js +13 -0
- package/features/formModel/FormModelFactory.js.map +1 -0
- package/features/formModel/FormView.d.ts +23 -0
- package/features/formModel/FormView.js +138 -0
- package/features/formModel/FormView.js.map +1 -0
- package/features/formModel/abstractions.d.ts +286 -0
- package/features/formModel/abstractions.js +54 -0
- package/features/formModel/abstractions.js.map +1 -0
- package/features/formModel/feature.d.ts +3 -0
- package/features/formModel/feature.js +16 -0
- package/features/formModel/feature.js.map +1 -0
- package/features/formModel/index.d.ts +10 -0
- package/features/formModel/index.js +14 -0
- package/features/formModel/index.js.map +1 -0
- package/features/formModel/useFieldRenderers.d.ts +2 -0
- package/features/formModel/useFieldRenderers.js +19 -0
- package/features/formModel/useFieldRenderers.js.map +1 -0
- package/features/security/LogIn/LogInGateway.d.ts +2 -2
- package/features/security/LogIn/LogInGateway.js +2 -2
- package/features/security/LogIn/LogInGateway.js.map +1 -1
- package/features/wcp/WcpGateway.d.ts +2 -2
- package/features/wcp/WcpGateway.js +2 -2
- package/features/wcp/WcpGateway.js.map +1 -1
- package/hooks/index.d.ts +1 -0
- package/hooks/index.js +1 -0
- package/hooks/index.js.map +1 -1
- package/hooks/useDialog.d.ts +9 -29
- package/hooks/useDialog.js +16 -24
- package/hooks/useDialog.js.map +1 -1
- package/hooks/useOpenDialog.d.ts +7 -0
- package/hooks/useOpenDialog.js +18 -0
- package/hooks/useOpenDialog.js.map +1 -0
- package/index.d.ts +5 -0
- package/index.js +5 -0
- package/index.js.map +1 -1
- package/package.json +30 -30
- package/permissions/createHasPermission.d.ts +3 -2
- package/permissions/createHasPermission.js +4 -8
- package/permissions/createHasPermission.js.map +1 -1
- package/permissions/createPermissions.d.ts +6 -0
- package/permissions/createPermissions.js +201 -0
- package/permissions/createPermissions.js.map +1 -0
- package/permissions/createPermissions.test.d.ts +1 -0
- package/permissions/createPermissions.test.js +177 -0
- package/permissions/createPermissions.test.js.map +1 -0
- package/permissions/index.d.ts +1 -0
- package/permissions/index.js +1 -0
- package/permissions/index.js.map +1 -1
- package/permissions/types.d.ts +5 -0
- package/permissions/types.js.map +1 -1
- package/permissions/usePermissions.d.ts +2 -1
- package/permissions/usePermissions.js +4 -175
- package/permissions/usePermissions.js.map +1 -1
- package/presentation/installation/presenters/SystemInstaller/SystemInstallerGateway.d.ts +2 -2
- package/presentation/installation/presenters/SystemInstaller/SystemInstallerGateway.js +2 -2
- package/presentation/installation/presenters/SystemInstaller/SystemInstallerGateway.js.map +1 -1
- package/permissions/createHasPermission.test.js +0 -206
- package/permissions/createHasPermission.test.js.map +0 -1
- /package/{permissions/createHasPermission.test.d.ts → features/formModel/FieldBuilder.test.d.ts} +0 -0
package/hooks/useDialog.js
CHANGED
|
@@ -1,28 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
options
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
});
|
|
15
|
-
},
|
|
16
|
-
hideDialog: () => {
|
|
17
|
-
ui.setState(ui => {
|
|
18
|
-
return {
|
|
19
|
-
...ui,
|
|
20
|
-
dialog: null
|
|
21
|
-
};
|
|
22
|
-
});
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { useDialogParamsContext } from "../components/Dialogs/DialogParamsContext.js";
|
|
3
|
+
export function useDialog(schema) {
|
|
4
|
+
const {
|
|
5
|
+
params: rawParams,
|
|
6
|
+
closeDialog
|
|
7
|
+
} = useDialogParamsContext();
|
|
8
|
+
const params = useMemo(() => {
|
|
9
|
+
if (schema) {
|
|
10
|
+
return schema.parse(rawParams);
|
|
23
11
|
}
|
|
12
|
+
return rawParams;
|
|
13
|
+
}, [rawParams, schema]);
|
|
14
|
+
return {
|
|
15
|
+
params,
|
|
16
|
+
closeDialog
|
|
24
17
|
};
|
|
25
|
-
}
|
|
26
|
-
export { useDialog };
|
|
18
|
+
}
|
|
27
19
|
|
|
28
20
|
//# sourceMappingURL=useDialog.js.map
|
package/hooks/useDialog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["useMemo","useDialogParamsContext","useDialog","schema","params","rawParams","closeDialog","parse"],"sources":["useDialog.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport type { z } from \"zod\";\nimport { useDialogParamsContext } from \"~/components/Dialogs/DialogParamsContext.js\";\n\nexport function useDialog<T extends z.ZodTypeAny>(\n schema: T\n): { params: z.infer<T>; closeDialog: () => void };\nexport function useDialog(): { params: Record<string, unknown>; closeDialog: () => void };\nexport function useDialog(schema?: z.ZodTypeAny) {\n const { params: rawParams, closeDialog } = useDialogParamsContext();\n\n const params = useMemo(() => {\n if (schema) {\n return schema.parse(rawParams);\n }\n return rawParams;\n }, [rawParams, schema]);\n\n return { params, closeDialog };\n}\n"],"mappings":"AAAA,SAASA,OAAO,QAAQ,OAAO;AAE/B,SAASC,sBAAsB;AAM/B,OAAO,SAASC,SAASA,CAACC,MAAqB,EAAE;EAC7C,MAAM;IAAEC,MAAM,EAAEC,SAAS;IAAEC;EAAY,CAAC,GAAGL,sBAAsB,CAAC,CAAC;EAEnE,MAAMG,MAAM,GAAGJ,OAAO,CAAC,MAAM;IACzB,IAAIG,MAAM,EAAE;MACR,OAAOA,MAAM,CAACI,KAAK,CAACF,SAAS,CAAC;IAClC;IACA,OAAOA,SAAS;EACpB,CAAC,EAAE,CAACA,SAAS,EAAEF,MAAM,CAAC,CAAC;EAEvB,OAAO;IAAEC,MAAM;IAAEE;EAAY,CAAC;AAClC","ignoreList":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
export declare function useOpenDialog<T extends z.ZodTypeAny>(schema: T): {
|
|
3
|
+
openDialog: (name: string, params: z.infer<T>) => void;
|
|
4
|
+
};
|
|
5
|
+
export declare function useOpenDialog(): {
|
|
6
|
+
openDialog: (name: string, params: Record<string, unknown>) => void;
|
|
7
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useDialogs } from "../components/Dialogs/useDialogs.js";
|
|
3
|
+
export function useOpenDialog(schema) {
|
|
4
|
+
const {
|
|
5
|
+
openNamedDialog
|
|
6
|
+
} = useDialogs();
|
|
7
|
+
const openDialog = useCallback((name, params) => {
|
|
8
|
+
if (schema) {
|
|
9
|
+
schema.parse(params);
|
|
10
|
+
}
|
|
11
|
+
openNamedDialog(name, params);
|
|
12
|
+
}, [openNamedDialog, schema]);
|
|
13
|
+
return {
|
|
14
|
+
openDialog
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=useOpenDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useCallback","useDialogs","useOpenDialog","schema","openNamedDialog","openDialog","name","params","parse"],"sources":["useOpenDialog.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport type { z } from \"zod\";\nimport { useDialogs } from \"~/components/Dialogs/useDialogs.js\";\n\nexport function useOpenDialog<T extends z.ZodTypeAny>(\n schema: T\n): { openDialog: (name: string, params: z.infer<T>) => void };\nexport function useOpenDialog(): {\n openDialog: (name: string, params: Record<string, unknown>) => void;\n};\nexport function useOpenDialog(schema?: z.ZodTypeAny) {\n const { openNamedDialog } = useDialogs();\n\n const openDialog = useCallback(\n (name: string, params: Record<string, unknown>) => {\n if (schema) {\n schema.parse(params);\n }\n openNamedDialog(name, params);\n },\n [openNamedDialog, schema]\n );\n\n return { openDialog };\n}\n"],"mappings":"AAAA,SAASA,WAAW,QAAQ,OAAO;AAEnC,SAASC,UAAU;AAQnB,OAAO,SAASC,aAAaA,CAACC,MAAqB,EAAE;EACjD,MAAM;IAAEC;EAAgB,CAAC,GAAGH,UAAU,CAAC,CAAC;EAExC,MAAMI,UAAU,GAAGL,WAAW,CAC1B,CAACM,IAAY,EAAEC,MAA+B,KAAK;IAC/C,IAAIJ,MAAM,EAAE;MACRA,MAAM,CAACK,KAAK,CAACD,MAAM,CAAC;IACxB;IACAH,eAAe,CAACE,IAAI,EAAEC,MAAM,CAAC;EACjC,CAAC,EACD,CAACH,eAAe,EAAED,MAAM,CAC5B,CAAC;EAED,OAAO;IAAEE;EAAW,CAAC;AACzB","ignoreList":[]}
|
package/index.d.ts
CHANGED
|
@@ -35,3 +35,8 @@ export { useAuthentication } from "./presentation/security/hooks/useAuthenticati
|
|
|
35
35
|
export { useBuildParams } from "./presentation/buildParams/useBuildParams.js";
|
|
36
36
|
export { useSecurity } from "./presentation/security/hooks/useSecurity.js";
|
|
37
37
|
export * from "@webiny/app/renderApp.js";
|
|
38
|
+
export { FormModelFactory, FormModel } from "./features/formModel/abstractions.js";
|
|
39
|
+
export type { IFormModelFactory, IFormModelConfig, ILayoutBuilder, IFieldBuilder, ISelectFieldBuilder, IFieldBuilderRegistry, IFormModel, IField, ISelectField, FieldTypeMap, IFieldConfig, IFieldVM, IFieldValidation, IFormVM, IFormError, IValueOption, IRowNode, IRowNodeVM, LayoutNode, LayoutNodeVM, LayoutPosition, IPositionedLayoutNode, ILayoutNodeHandle, ILayoutModifier, IFormModifier, BeforeChangeCallback, AfterChangeCallback, AfterSetValueCallback } from "./features/formModel/abstractions.js";
|
|
40
|
+
export { FormView } from "./features/formModel/FormView.js";
|
|
41
|
+
export { useFieldRenderers } from "./features/formModel/useFieldRenderers.js";
|
|
42
|
+
export type { FieldRenderers, FieldRendererComponent } from "./features/formModel/FormView.js";
|
package/index.js
CHANGED
|
@@ -44,4 +44,9 @@ export { useBuildParams } from "./presentation/buildParams/useBuildParams.js";
|
|
|
44
44
|
export { useSecurity } from "./presentation/security/hooks/useSecurity.js";
|
|
45
45
|
export * from "@webiny/app/renderApp.js";
|
|
46
46
|
|
|
47
|
+
// FormModel
|
|
48
|
+
export { FormModelFactory, FormModel } from "./features/formModel/abstractions.js";
|
|
49
|
+
export { FormView } from "./features/formModel/FormView.js";
|
|
50
|
+
export { useFieldRenderers } from "./features/formModel/useFieldRenderers.js";
|
|
51
|
+
|
|
47
52
|
//# sourceMappingURL=index.js.map
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Admin","HasPermission","SecureRoute","FileManager","FileManagerRenderer","SystemInstallerProvider","BuildParamsFeature","useWcp","useTenantContext","useIdentity","useAuthentication","useBuildParams","useSecurity"],"sources":["index.ts"],"sourcesContent":["export * from \"@webiny/app\";\nexport type { HigherOrderComponent, ProviderProps, ComposeProps } from \"@webiny/app\";\n// UI components\nexport * from \"./base/ui/Tags.js\";\nexport * from \"./base/ui/Layout.js\";\nexport * from \"./base/ui/TenantSelector.js\";\nexport type { LayoutProps } from \"./base/ui/Layout.js\";\nexport * from \"./base/ui/Navigation.js\";\nexport * from \"./base/ui/Brand.js\";\nexport * from \"./base/ui/Logo.js\";\nexport * from \"./base/ui/UserMenu.js\";\nexport * from \"./base/ui/LoginScreen.js\";\nexport * from \"./base/ui/CenteredView.js\";\nexport * from \"./base/ui/Dashboard.js\";\nexport * from \"./base/ui/NotFound.js\";\n\n// Base admin app\nexport { Admin } from \"./base/Admin.js\";\nexport * from \"./config/AdminConfig.js\";\n\nexport type { AdminProps } from \"./base/Admin.js\";\n\n// Plugins\nexport * from \"./base/plugins/AddGraphQLQuerySelection.js\";\n\n// Permissions\nexport * from \"./permissions/index.js\";\n\n// Components\nexport * from \"./components/index.js\";\nexport type { RichTextValueWithHtml } from \"./components/index.js\";\nexport { HasPermission } from \"./presentation/security/components/HasPermission.js\";\nexport { SecureRoute } from \"./presentation/security/components/SecureRoute.js\";\n\nexport { FileManager, FileManagerRenderer } from \"./base/ui/FileManager.js\";\nexport type {\n FileManagerProps,\n FileManagerRendererProps,\n FileManagerFileItem,\n FileManagerOnChange\n} from \"./base/ui/FileManager.js\";\n\nexport { SystemInstallerProvider } from \"./presentation/installation/components/SystemInstaller/index.js\";\n\n// Feature types\nexport type { AaclPermission } from \"./features/wcp/types.js\";\nexport type { Tenant } from \"./features/tenancy/types.js\";\n\nexport { BuildParamsFeature } from \"./features/buildParams/feature.js\";\n\n// Hooks\nexport * from \"./hooks/index.js\";\nexport { useWcp } from \"./presentation/wcp/useWcp.js\";\nexport { useTenantContext } from \"./presentation/tenancy/useTenantContext.js\";\nexport { useIdentity } from \"./presentation/security/hooks/useIdentity.js\";\nexport { useAuthentication } from \"./presentation/security/hooks/useAuthentication.js\";\nexport { useBuildParams } from \"./presentation/buildParams/useBuildParams.js\";\n\n// Legacy hook for easier migration\nexport { useSecurity } from \"./presentation/security/hooks/useSecurity.js\";\n\nexport * from \"@webiny/app/renderApp.js\";\n"],"mappings":"AAAA,cAAc,aAAa;AAE3B;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,SAASA,KAAK;AACd;AAIA;AACA;;AAEA;AACA;;AAEA;AACA;AAEA,SAASC,aAAa;AACtB,SAASC,WAAW;AAEpB,SAASC,WAAW,EAAEC,mBAAmB;AAQzC,SAASC,uBAAuB;;AAEhC;;AAIA,SAASC,kBAAkB;;AAE3B;AACA;AACA,SAASC,MAAM;AACf,SAASC,gBAAgB;AACzB,SAASC,WAAW;AACpB,SAASC,iBAAiB;AAC1B,SAASC,cAAc;;AAEvB;AACA,SAASC,WAAW;AAEpB,cAAc,0BAA0B","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["Admin","HasPermission","SecureRoute","FileManager","FileManagerRenderer","SystemInstallerProvider","BuildParamsFeature","useWcp","useTenantContext","useIdentity","useAuthentication","useBuildParams","useSecurity","FormModelFactory","FormModel","FormView","useFieldRenderers"],"sources":["index.ts"],"sourcesContent":["export * from \"@webiny/app\";\nexport type { HigherOrderComponent, ProviderProps, ComposeProps } from \"@webiny/app\";\n// UI components\nexport * from \"./base/ui/Tags.js\";\nexport * from \"./base/ui/Layout.js\";\nexport * from \"./base/ui/TenantSelector.js\";\nexport type { LayoutProps } from \"./base/ui/Layout.js\";\nexport * from \"./base/ui/Navigation.js\";\nexport * from \"./base/ui/Brand.js\";\nexport * from \"./base/ui/Logo.js\";\nexport * from \"./base/ui/UserMenu.js\";\nexport * from \"./base/ui/LoginScreen.js\";\nexport * from \"./base/ui/CenteredView.js\";\nexport * from \"./base/ui/Dashboard.js\";\nexport * from \"./base/ui/NotFound.js\";\n\n// Base admin app\nexport { Admin } from \"./base/Admin.js\";\nexport * from \"./config/AdminConfig.js\";\n\nexport type { AdminProps } from \"./base/Admin.js\";\n\n// Plugins\nexport * from \"./base/plugins/AddGraphQLQuerySelection.js\";\n\n// Permissions\nexport * from \"./permissions/index.js\";\n\n// Components\nexport * from \"./components/index.js\";\nexport type { RichTextValueWithHtml } from \"./components/index.js\";\nexport { HasPermission } from \"./presentation/security/components/HasPermission.js\";\nexport { SecureRoute } from \"./presentation/security/components/SecureRoute.js\";\n\nexport { FileManager, FileManagerRenderer } from \"./base/ui/FileManager.js\";\nexport type {\n FileManagerProps,\n FileManagerRendererProps,\n FileManagerFileItem,\n FileManagerOnChange\n} from \"./base/ui/FileManager.js\";\n\nexport { SystemInstallerProvider } from \"./presentation/installation/components/SystemInstaller/index.js\";\n\n// Feature types\nexport type { AaclPermission } from \"./features/wcp/types.js\";\nexport type { Tenant } from \"./features/tenancy/types.js\";\n\nexport { BuildParamsFeature } from \"./features/buildParams/feature.js\";\n\n// Hooks\nexport * from \"./hooks/index.js\";\nexport { useWcp } from \"./presentation/wcp/useWcp.js\";\nexport { useTenantContext } from \"./presentation/tenancy/useTenantContext.js\";\nexport { useIdentity } from \"./presentation/security/hooks/useIdentity.js\";\nexport { useAuthentication } from \"./presentation/security/hooks/useAuthentication.js\";\nexport { useBuildParams } from \"./presentation/buildParams/useBuildParams.js\";\n\n// Legacy hook for easier migration\nexport { useSecurity } from \"./presentation/security/hooks/useSecurity.js\";\n\nexport * from \"@webiny/app/renderApp.js\";\n\n// FormModel\nexport { FormModelFactory, FormModel } from \"./features/formModel/abstractions.js\";\nexport type {\n IFormModelFactory,\n IFormModelConfig,\n ILayoutBuilder,\n IFieldBuilder,\n ISelectFieldBuilder,\n IFieldBuilderRegistry,\n IFormModel,\n IField,\n ISelectField,\n FieldTypeMap,\n IFieldConfig,\n IFieldVM,\n IFieldValidation,\n IFormVM,\n IFormError,\n IValueOption,\n IRowNode,\n IRowNodeVM,\n LayoutNode,\n LayoutNodeVM,\n LayoutPosition,\n IPositionedLayoutNode,\n ILayoutNodeHandle,\n ILayoutModifier,\n IFormModifier,\n BeforeChangeCallback,\n AfterChangeCallback,\n AfterSetValueCallback\n} from \"./features/formModel/abstractions.js\";\nexport { FormView } from \"./features/formModel/FormView.js\";\nexport { useFieldRenderers } from \"./features/formModel/useFieldRenderers.js\";\nexport type { FieldRenderers, FieldRendererComponent } from \"./features/formModel/FormView.js\";\n"],"mappings":"AAAA,cAAc,aAAa;AAE3B;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,SAASA,KAAK;AACd;AAIA;AACA;;AAEA;AACA;;AAEA;AACA;AAEA,SAASC,aAAa;AACtB,SAASC,WAAW;AAEpB,SAASC,WAAW,EAAEC,mBAAmB;AAQzC,SAASC,uBAAuB;;AAEhC;;AAIA,SAASC,kBAAkB;;AAE3B;AACA;AACA,SAASC,MAAM;AACf,SAASC,gBAAgB;AACzB,SAASC,WAAW;AACpB,SAASC,iBAAiB;AAC1B,SAASC,cAAc;;AAEvB;AACA,SAASC,WAAW;AAEpB,cAAc,0BAA0B;;AAExC;AACA,SAASC,gBAAgB,EAAEC,SAAS;AA+BpC,SAASC,QAAQ;AACjB,SAASC,iBAAiB","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/app-admin",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0-beta.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"description": "A collection of plugins that together form a complete admin interface, customizable and extensible with Webiny apps and plugins.",
|
|
@@ -16,26 +16,26 @@
|
|
|
16
16
|
"@emotion/css": "11.13.5",
|
|
17
17
|
"@emotion/react": "11.14.0",
|
|
18
18
|
"@emotion/styled": "11.14.1",
|
|
19
|
-
"@iconify/json": "2.2.
|
|
19
|
+
"@iconify/json": "2.2.462",
|
|
20
20
|
"@svgr/webpack": "8.1.0",
|
|
21
|
-
"@types/react": "18.
|
|
22
|
-
"@webiny/admin-ui": "6.
|
|
23
|
-
"@webiny/app": "6.
|
|
21
|
+
"@types/react": "18.3.28",
|
|
22
|
+
"@webiny/admin-ui": "6.2.0-beta.0",
|
|
23
|
+
"@webiny/app": "6.2.0-beta.0",
|
|
24
24
|
"@webiny/di": "0.2.3",
|
|
25
|
-
"@webiny/feature": "6.
|
|
26
|
-
"@webiny/form": "6.
|
|
27
|
-
"@webiny/icons": "6.
|
|
28
|
-
"@webiny/lexical-converter": "6.
|
|
29
|
-
"@webiny/lexical-editor": "6.
|
|
30
|
-
"@webiny/lexical-theme": "6.
|
|
31
|
-
"@webiny/plugins": "6.
|
|
32
|
-
"@webiny/react-composition": "6.
|
|
33
|
-
"@webiny/react-properties": "6.
|
|
34
|
-
"@webiny/telemetry": "6.
|
|
35
|
-
"@webiny/ui": "6.
|
|
36
|
-
"@webiny/utils": "6.
|
|
37
|
-
"@webiny/validation": "6.
|
|
38
|
-
"@webiny/wcp": "6.
|
|
25
|
+
"@webiny/feature": "6.2.0-beta.0",
|
|
26
|
+
"@webiny/form": "6.2.0-beta.0",
|
|
27
|
+
"@webiny/icons": "6.2.0-beta.0",
|
|
28
|
+
"@webiny/lexical-converter": "6.2.0-beta.0",
|
|
29
|
+
"@webiny/lexical-editor": "6.2.0-beta.0",
|
|
30
|
+
"@webiny/lexical-theme": "6.2.0-beta.0",
|
|
31
|
+
"@webiny/plugins": "6.2.0-beta.0",
|
|
32
|
+
"@webiny/react-composition": "6.2.0-beta.0",
|
|
33
|
+
"@webiny/react-properties": "6.2.0-beta.0",
|
|
34
|
+
"@webiny/telemetry": "6.2.0-beta.0",
|
|
35
|
+
"@webiny/ui": "6.2.0-beta.0",
|
|
36
|
+
"@webiny/utils": "6.2.0-beta.0",
|
|
37
|
+
"@webiny/validation": "6.2.0-beta.0",
|
|
38
|
+
"@webiny/wcp": "6.2.0-beta.0",
|
|
39
39
|
"apollo-cache": "1.3.5",
|
|
40
40
|
"apollo-client": "2.6.10",
|
|
41
41
|
"apollo-link": "1.2.14",
|
|
@@ -46,21 +46,21 @@
|
|
|
46
46
|
"graphql-tag": "2.12.6",
|
|
47
47
|
"history": "5.3.0",
|
|
48
48
|
"is-hotkey": "0.2.0",
|
|
49
|
-
"lodash": "4.
|
|
50
|
-
"markdown-to-jsx": "9.7.
|
|
51
|
-
"minimatch": "10.2.
|
|
49
|
+
"lodash": "4.18.1",
|
|
50
|
+
"markdown-to-jsx": "9.7.15",
|
|
51
|
+
"minimatch": "10.2.5",
|
|
52
52
|
"mobx": "6.15.0",
|
|
53
53
|
"mobx-react-lite": "4.1.1",
|
|
54
54
|
"monaco-editor": "0.53.0",
|
|
55
|
-
"
|
|
56
|
-
"react": "18.
|
|
57
|
-
"react-
|
|
58
|
-
"react-resizable-panels": "4.7.6",
|
|
55
|
+
"react": "18.3.1",
|
|
56
|
+
"react-dom": "18.3.1",
|
|
57
|
+
"react-resizable-panels": "4.10.0",
|
|
59
58
|
"react-transition-group": "4.4.5",
|
|
60
59
|
"react-virtualized": "9.22.6",
|
|
61
60
|
"reset-css": "5.0.2",
|
|
62
61
|
"tinycolor2": "1.6.0",
|
|
63
|
-
"unicode-emoji-json": "0.8.0"
|
|
62
|
+
"unicode-emoji-json": "0.8.0",
|
|
63
|
+
"zod": "4.3.6"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@emotion/babel-plugin": "11.13.5",
|
|
@@ -72,10 +72,10 @@
|
|
|
72
72
|
"@types/react-transition-group": "4.4.12",
|
|
73
73
|
"@types/store": "2.0.5",
|
|
74
74
|
"@types/tinycolor2": "1.4.6",
|
|
75
|
-
"@webiny/build-tools": "6.
|
|
75
|
+
"@webiny/build-tools": "6.2.0-beta.0",
|
|
76
76
|
"rimraf": "6.1.3",
|
|
77
77
|
"typescript": "5.9.3",
|
|
78
|
-
"vitest": "4.1.
|
|
78
|
+
"vitest": "4.1.4"
|
|
79
79
|
},
|
|
80
80
|
"publishConfig": {
|
|
81
81
|
"access": "public",
|
|
@@ -98,5 +98,5 @@
|
|
|
98
98
|
]
|
|
99
99
|
}
|
|
100
100
|
},
|
|
101
|
-
"gitHead": "
|
|
101
|
+
"gitHead": "3d3148358b6febbc857371930871743bec3b3939"
|
|
102
102
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type {
|
|
3
|
-
|
|
2
|
+
import type { Abstraction } from "@webiny/di";
|
|
3
|
+
import type { HasPermissionProps, PermissionSchemaConfig, UsePermissionsResult } from "./types.js";
|
|
4
|
+
export declare function createHasPermission<const S extends PermissionSchemaConfig>(abstraction: Abstraction<UsePermissionsResult<S>>): React.FC<HasPermissionProps<S>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { useContainer } from "@webiny/app";
|
|
3
3
|
const BUILT_IN_ACTIONS = {
|
|
4
4
|
read: "canRead",
|
|
5
5
|
create: "canCreate",
|
|
@@ -8,13 +8,13 @@ const BUILT_IN_ACTIONS = {
|
|
|
8
8
|
publish: "canPublish",
|
|
9
9
|
unpublish: "canUnpublish"
|
|
10
10
|
};
|
|
11
|
-
export function createHasPermission(
|
|
12
|
-
const usePermissions = createUsePermissions(schema);
|
|
11
|
+
export function createHasPermission(abstraction) {
|
|
13
12
|
return function HasPermission({
|
|
14
13
|
children,
|
|
15
14
|
...props
|
|
16
15
|
}) {
|
|
17
|
-
const
|
|
16
|
+
const container = useContainer();
|
|
17
|
+
const permissions = container.resolve(abstraction);
|
|
18
18
|
const action = props.action;
|
|
19
19
|
const someActions = props.someActions;
|
|
20
20
|
const allActions = props.allActions;
|
|
@@ -28,10 +28,6 @@ export function createHasPermission(schema) {
|
|
|
28
28
|
if (method && typeof permissions[method] === "function") {
|
|
29
29
|
return permissions[method](entityId);
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
32
|
-
* // TODO cant be typed properly because of the dynamic nature of custom actions.
|
|
33
|
-
*/
|
|
34
|
-
// @ts-expect-error
|
|
35
31
|
return permissions.canAction(singleAction, entityId);
|
|
36
32
|
};
|
|
37
33
|
const check = entityId => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","
|
|
1
|
+
{"version":3,"names":["React","useContainer","BUILT_IN_ACTIONS","read","create","edit","delete","publish","unpublish","createHasPermission","abstraction","HasPermission","children","props","container","permissions","resolve","action","someActions","allActions","entities","entity","any","all","requireAll","checkAction","entityId","singleAction","canAccess","method","canAction","check","every","act","some","allowed","createElement","Fragment"],"sources":["createHasPermission.tsx"],"sourcesContent":["import React from \"react\";\nimport type { Abstraction } from \"@webiny/di\";\nimport type { HasPermissionProps, PermissionSchemaConfig, UsePermissionsResult } from \"./types.js\";\nimport { useContainer } from \"@webiny/app\";\n\nconst BUILT_IN_ACTIONS: Record<string, string> = {\n read: \"canRead\",\n create: \"canCreate\",\n edit: \"canEdit\",\n delete: \"canDelete\",\n publish: \"canPublish\",\n unpublish: \"canUnpublish\"\n};\n\nexport function createHasPermission<const S extends PermissionSchemaConfig>(\n abstraction: Abstraction<UsePermissionsResult<S>>\n): React.FC<HasPermissionProps<S>> {\n return function HasPermission({ children, ...props }) {\n const container = useContainer();\n const permissions = container.resolve(abstraction);\n\n const action = props.action as string | undefined;\n const someActions = props.someActions as string[] | undefined;\n const allActions = props.allActions as string[] | undefined;\n const entities: string[] = props.entity ? [props.entity] : (props.any ?? props.all ?? []);\n const requireAll = !!props.all;\n\n const checkAction = (entityId: string, singleAction: string | undefined): boolean => {\n if (!singleAction) {\n return permissions.canAccess(entityId);\n }\n const method = BUILT_IN_ACTIONS[singleAction] as keyof typeof permissions;\n if (method && typeof permissions[method] === \"function\") {\n return (permissions[method] as (entityId: string) => boolean)(entityId);\n }\n return (permissions.canAction as (action: string, entityId: string) => boolean)(\n singleAction,\n entityId\n );\n };\n\n const check = (entityId: string): boolean => {\n if (allActions) {\n return allActions.every(act => checkAction(entityId, act));\n }\n if (someActions) {\n return someActions.some(act => checkAction(entityId, act));\n }\n return checkAction(entityId, action);\n };\n\n const allowed = requireAll ? entities.every(check) : entities.some(check);\n\n return allowed ? <>{children}</> : null;\n };\n}\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AAGzB,SAASC,YAAY,QAAQ,aAAa;AAE1C,MAAMC,gBAAwC,GAAG;EAC7CC,IAAI,EAAE,SAAS;EACfC,MAAM,EAAE,WAAW;EACnBC,IAAI,EAAE,SAAS;EACfC,MAAM,EAAE,WAAW;EACnBC,OAAO,EAAE,YAAY;EACrBC,SAAS,EAAE;AACf,CAAC;AAED,OAAO,SAASC,mBAAmBA,CAC/BC,WAAiD,EAClB;EAC/B,OAAO,SAASC,aAAaA,CAAC;IAAEC,QAAQ;IAAE,GAAGC;EAAM,CAAC,EAAE;IAClD,MAAMC,SAAS,GAAGb,YAAY,CAAC,CAAC;IAChC,MAAMc,WAAW,GAAGD,SAAS,CAACE,OAAO,CAACN,WAAW,CAAC;IAElD,MAAMO,MAAM,GAAGJ,KAAK,CAACI,MAA4B;IACjD,MAAMC,WAAW,GAAGL,KAAK,CAACK,WAAmC;IAC7D,MAAMC,UAAU,GAAGN,KAAK,CAACM,UAAkC;IAC3D,MAAMC,QAAkB,GAAGP,KAAK,CAACQ,MAAM,GAAG,CAACR,KAAK,CAACQ,MAAM,CAAC,GAAIR,KAAK,CAACS,GAAG,IAAIT,KAAK,CAACU,GAAG,IAAI,EAAG;IACzF,MAAMC,UAAU,GAAG,CAAC,CAACX,KAAK,CAACU,GAAG;IAE9B,MAAME,WAAW,GAAGA,CAACC,QAAgB,EAAEC,YAAgC,KAAc;MACjF,IAAI,CAACA,YAAY,EAAE;QACf,OAAOZ,WAAW,CAACa,SAAS,CAACF,QAAQ,CAAC;MAC1C;MACA,MAAMG,MAAM,GAAG3B,gBAAgB,CAACyB,YAAY,CAA6B;MACzE,IAAIE,MAAM,IAAI,OAAOd,WAAW,CAACc,MAAM,CAAC,KAAK,UAAU,EAAE;QACrD,OAAQd,WAAW,CAACc,MAAM,CAAC,CAAmCH,QAAQ,CAAC;MAC3E;MACA,OAAQX,WAAW,CAACe,SAAS,CACzBH,YAAY,EACZD,QACJ,CAAC;IACL,CAAC;IAED,MAAMK,KAAK,GAAIL,QAAgB,IAAc;MACzC,IAAIP,UAAU,EAAE;QACZ,OAAOA,UAAU,CAACa,KAAK,CAACC,GAAG,IAAIR,WAAW,CAACC,QAAQ,EAAEO,GAAG,CAAC,CAAC;MAC9D;MACA,IAAIf,WAAW,EAAE;QACb,OAAOA,WAAW,CAACgB,IAAI,CAACD,GAAG,IAAIR,WAAW,CAACC,QAAQ,EAAEO,GAAG,CAAC,CAAC;MAC9D;MACA,OAAOR,WAAW,CAACC,QAAQ,EAAET,MAAM,CAAC;IACxC,CAAC;IAED,MAAMkB,OAAO,GAAGX,UAAU,GAAGJ,QAAQ,CAACY,KAAK,CAACD,KAAK,CAAC,GAAGX,QAAQ,CAACc,IAAI,CAACH,KAAK,CAAC;IAEzE,OAAOI,OAAO,gBAAGnC,KAAA,CAAAoC,aAAA,CAAApC,KAAA,CAAAqC,QAAA,QAAGzB,QAAW,CAAC,GAAG,IAAI;EAC3C,CAAC;AACL","ignoreList":[]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Abstraction } from "@webiny/di";
|
|
2
|
+
import type { PermissionSchemaConfig, UsePermissionsResult } from "./types.js";
|
|
3
|
+
export declare function createPermissionsAbstraction<const S extends PermissionSchemaConfig>(schema: S): Abstraction<UsePermissionsResult<S>>;
|
|
4
|
+
export declare function createPermissionsFeature<const S extends PermissionSchemaConfig>(schema: S, abstraction: Abstraction<UsePermissionsResult<S>>): import("@webiny/feature/admin").FeatureDefinition<{
|
|
5
|
+
permissions: UsePermissionsResult<S>;
|
|
6
|
+
}, []>;
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { createAbstraction } from "@webiny/feature/admin";
|
|
2
|
+
import { createFeature } from "@webiny/feature/admin";
|
|
3
|
+
import { IdentityContext } from "../features/security/IdentityContext/abstractions.js";
|
|
4
|
+
function buildEntityMap(schema) {
|
|
5
|
+
const map = new Map();
|
|
6
|
+
for (const entity of schema.entities ?? []) {
|
|
7
|
+
const actions = new Set();
|
|
8
|
+
for (const action of entity.actions ?? []) {
|
|
9
|
+
actions.add(action.name);
|
|
10
|
+
}
|
|
11
|
+
map.set(entity.id, {
|
|
12
|
+
permission: entity.permission,
|
|
13
|
+
actions,
|
|
14
|
+
hasOwn: entity.scopes.includes("own")
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return map;
|
|
18
|
+
}
|
|
19
|
+
function getEntity(entityMap, entityId) {
|
|
20
|
+
const entity = entityMap.get(entityId);
|
|
21
|
+
if (!entity) {
|
|
22
|
+
throw new Error(`Unknown entity "${entityId}" in permission schema.`);
|
|
23
|
+
}
|
|
24
|
+
return entity;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Check whether the identity has unrestricted full access for the given schema prefix.
|
|
29
|
+
* Stricter than the legacy check: `{ name: "wb.*", rwd: "r" }` is NOT full access.
|
|
30
|
+
*/
|
|
31
|
+
function hasFullSchemaAccess(identity, prefix) {
|
|
32
|
+
const fullAccessName = `${prefix}.*`;
|
|
33
|
+
const permission = identity.getPermission(fullAccessName);
|
|
34
|
+
if (!permission) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
// If any restricting keys are present, this is not full access.
|
|
38
|
+
if (typeof permission.rwd === "string" || typeof permission.pw === "string") {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
class SchemaPermissions {
|
|
44
|
+
constructor(schema, identityContext) {
|
|
45
|
+
this.schema = schema;
|
|
46
|
+
this.entityMap = buildEntityMap(schema);
|
|
47
|
+
this.identityContext = identityContext;
|
|
48
|
+
}
|
|
49
|
+
get identity() {
|
|
50
|
+
return this.identityContext.getIdentity();
|
|
51
|
+
}
|
|
52
|
+
get fullAccess() {
|
|
53
|
+
return hasFullSchemaAccess(this.identity, this.schema.prefix);
|
|
54
|
+
}
|
|
55
|
+
canAccess = entityId => {
|
|
56
|
+
if (this.fullAccess) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
const entity = getEntity(this.entityMap, entityId);
|
|
60
|
+
return this.identity.getPermissions(entity.permission).length > 0;
|
|
61
|
+
};
|
|
62
|
+
canRead = entityId => {
|
|
63
|
+
if (this.fullAccess) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
const entity = getEntity(this.entityMap, entityId);
|
|
67
|
+
const permissions = this.identity.getPermissions(entity.permission);
|
|
68
|
+
if (!permissions.length) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
return permissions.some(permission => {
|
|
72
|
+
if (typeof permission.rwd !== "string") {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
return permission.rwd.includes("r");
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
canCreate = entityId => {
|
|
79
|
+
if (this.fullAccess) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
const entity = getEntity(this.entityMap, entityId);
|
|
83
|
+
const permissions = this.identity.getPermissions(entity.permission);
|
|
84
|
+
if (!permissions.length) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
return permissions.some(permission => {
|
|
88
|
+
if (typeof permission.rwd !== "string") {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
return permission.rwd.includes("w");
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
canEdit = (entityId, item) => {
|
|
95
|
+
if (this.fullAccess) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
const entity = getEntity(this.entityMap, entityId);
|
|
99
|
+
const permissions = this.identity.getPermissions(entity.permission);
|
|
100
|
+
if (!permissions.length) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
return permissions.some(permission => {
|
|
104
|
+
if (permission.own) {
|
|
105
|
+
if (!item?.createdBy) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
return item.createdBy.id === this.identity.id;
|
|
109
|
+
}
|
|
110
|
+
if (typeof permission.rwd !== "string") {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
return permission.rwd.includes("w");
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
canDelete = (entityId, item) => {
|
|
117
|
+
if (this.fullAccess) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
const entity = getEntity(this.entityMap, entityId);
|
|
121
|
+
const permissions = this.identity.getPermissions(entity.permission);
|
|
122
|
+
if (!permissions.length) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
return permissions.some(permission => {
|
|
126
|
+
if (permission.own) {
|
|
127
|
+
return item?.createdBy?.id === this.identity.id;
|
|
128
|
+
}
|
|
129
|
+
if (typeof permission.rwd !== "string") {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return permission.rwd.includes("d");
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
canPublish = entityId => {
|
|
136
|
+
if (this.fullAccess) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
const entity = getEntity(this.entityMap, entityId);
|
|
140
|
+
const permissions = this.identity.getPermissions(entity.permission);
|
|
141
|
+
if (!permissions.length) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
return permissions.some(permission => {
|
|
145
|
+
return permission.pw?.includes("p");
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
canUnpublish = entityId => {
|
|
149
|
+
if (this.fullAccess) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
const entity = getEntity(this.entityMap, entityId);
|
|
153
|
+
const permissions = this.identity.getPermissions(entity.permission);
|
|
154
|
+
if (!permissions.length) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
return permissions.some(permission => {
|
|
158
|
+
return permission.pw?.includes("u");
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
canAction = (action, entityId) => {
|
|
162
|
+
if (this.fullAccess) {
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
const entity = getEntity(this.entityMap, entityId);
|
|
166
|
+
const permissions = this.identity.getPermissions(entity.permission);
|
|
167
|
+
if (!permissions.length) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
return permissions.some(permission => {
|
|
171
|
+
return permission[action] === true;
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
export function createPermissionsAbstraction(schema) {
|
|
176
|
+
return createAbstraction(`${schema.prefix}:Permissions`);
|
|
177
|
+
}
|
|
178
|
+
export function createPermissionsFeature(schema, abstraction) {
|
|
179
|
+
class PermissionsImpl extends SchemaPermissions {
|
|
180
|
+
constructor(identityContext) {
|
|
181
|
+
super(schema, identityContext);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const Implementation = abstraction.createImplementation({
|
|
185
|
+
implementation: PermissionsImpl,
|
|
186
|
+
dependencies: [IdentityContext]
|
|
187
|
+
});
|
|
188
|
+
return createFeature({
|
|
189
|
+
name: `${schema.prefix}:Permissions`,
|
|
190
|
+
register(container) {
|
|
191
|
+
container.register(Implementation).inSingletonScope();
|
|
192
|
+
},
|
|
193
|
+
resolve(container) {
|
|
194
|
+
return {
|
|
195
|
+
permissions: container.resolve(abstraction)
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
//# sourceMappingURL=createPermissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createAbstraction","createFeature","IdentityContext","buildEntityMap","schema","map","Map","entity","entities","actions","Set","action","add","name","set","id","permission","hasOwn","scopes","includes","getEntity","entityMap","entityId","get","Error","hasFullSchemaAccess","identity","prefix","fullAccessName","getPermission","rwd","pw","SchemaPermissions","constructor","identityContext","getIdentity","fullAccess","canAccess","getPermissions","length","canRead","permissions","some","canCreate","canEdit","item","own","createdBy","canDelete","canPublish","canUnpublish","canAction","createPermissionsAbstraction","createPermissionsFeature","abstraction","PermissionsImpl","Implementation","createImplementation","implementation","dependencies","register","container","inSingletonScope","resolve"],"sources":["createPermissions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport { createFeature } from \"@webiny/feature/admin\";\nimport { IdentityContext } from \"~/features/security/IdentityContext/abstractions.js\";\nimport type { IIdentityContext } from \"~/features/security/IdentityContext/abstractions.js\";\nimport type { Identity } from \"~/domain/Identity.js\";\nimport type { Abstraction } from \"@webiny/di\";\nimport type { PermissionSchemaConfig, OwnableItem, UsePermissionsResult } from \"./types.js\";\n\ninterface EntityLookup {\n permission: string;\n actions: Set<string>;\n hasOwn: boolean;\n}\n\nfunction buildEntityMap(schema: PermissionSchemaConfig): Map<string, EntityLookup> {\n const map = new Map<string, EntityLookup>();\n for (const entity of schema.entities ?? []) {\n const actions = new Set<string>();\n for (const action of entity.actions ?? []) {\n actions.add(action.name);\n }\n map.set(entity.id, {\n permission: entity.permission,\n actions,\n hasOwn: entity.scopes.includes(\"own\")\n });\n }\n return map;\n}\n\nfunction getEntity(entityMap: Map<string, EntityLookup>, entityId: string): EntityLookup {\n const entity = entityMap.get(entityId);\n if (!entity) {\n throw new Error(`Unknown entity \"${entityId}\" in permission schema.`);\n }\n return entity;\n}\n\n/**\n * Check whether the identity has unrestricted full access for the given schema prefix.\n * Stricter than the legacy check: `{ name: \"wb.*\", rwd: \"r\" }` is NOT full access.\n */\nfunction hasFullSchemaAccess(identity: Identity, prefix: string): boolean {\n const fullAccessName = `${prefix}.*`;\n const permission = identity.getPermission(fullAccessName);\n if (!permission) {\n return false;\n }\n // If any restricting keys are present, this is not full access.\n if (typeof permission.rwd === \"string\" || typeof permission.pw === \"string\") {\n return false;\n }\n return true;\n}\n\nclass SchemaPermissions<S extends PermissionSchemaConfig> {\n private readonly schema: S;\n private readonly entityMap: Map<string, EntityLookup>;\n private readonly identityContext: IIdentityContext;\n\n constructor(schema: S, identityContext: IIdentityContext) {\n this.schema = schema;\n this.entityMap = buildEntityMap(schema);\n this.identityContext = identityContext;\n }\n\n private get identity(): Identity {\n return this.identityContext.getIdentity();\n }\n\n private get fullAccess(): boolean {\n return hasFullSchemaAccess(this.identity, this.schema.prefix);\n }\n\n canAccess = (entityId: string): boolean => {\n if (this.fullAccess) {\n return true;\n }\n const entity = getEntity(this.entityMap, entityId);\n return this.identity.getPermissions(entity.permission).length > 0;\n };\n\n canRead = (entityId: string): boolean => {\n if (this.fullAccess) {\n return true;\n }\n const entity = getEntity(this.entityMap, entityId);\n const permissions = this.identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n return permission.rwd.includes(\"r\");\n });\n };\n\n canCreate = (entityId: string): boolean => {\n if (this.fullAccess) {\n return true;\n }\n const entity = getEntity(this.entityMap, entityId);\n const permissions = this.identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n return permission.rwd.includes(\"w\");\n });\n };\n\n canEdit = (entityId: string, item?: OwnableItem): boolean => {\n if (this.fullAccess) {\n return true;\n }\n const entity = getEntity(this.entityMap, entityId);\n const permissions = this.identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n if (permission.own) {\n if (!item?.createdBy) {\n return true;\n }\n return item.createdBy.id === this.identity.id;\n }\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n return permission.rwd.includes(\"w\");\n });\n };\n\n canDelete = (entityId: string, item?: OwnableItem): boolean => {\n if (this.fullAccess) {\n return true;\n }\n const entity = getEntity(this.entityMap, entityId);\n const permissions = this.identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n if (permission.own) {\n return item?.createdBy?.id === this.identity.id;\n }\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n return permission.rwd.includes(\"d\");\n });\n };\n\n canPublish = (entityId: string): boolean => {\n if (this.fullAccess) {\n return true;\n }\n const entity = getEntity(this.entityMap, entityId);\n const permissions = this.identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n return permission.pw?.includes(\"p\");\n });\n };\n\n canUnpublish = (entityId: string): boolean => {\n if (this.fullAccess) {\n return true;\n }\n const entity = getEntity(this.entityMap, entityId);\n const permissions = this.identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n return permission.pw?.includes(\"u\");\n });\n };\n\n canAction = (action: string, entityId: string): boolean => {\n if (this.fullAccess) {\n return true;\n }\n const entity = getEntity(this.entityMap, entityId);\n const permissions = this.identity.getPermissions(entity.permission);\n if (!permissions.length) {\n return false;\n }\n return permissions.some(permission => {\n return permission[action] === true;\n });\n };\n}\n\nexport function createPermissionsAbstraction<const S extends PermissionSchemaConfig>(schema: S) {\n return createAbstraction<UsePermissionsResult<S>>(`${schema.prefix}:Permissions`);\n}\n\nexport function createPermissionsFeature<const S extends PermissionSchemaConfig>(\n schema: S,\n abstraction: Abstraction<UsePermissionsResult<S>>\n) {\n class PermissionsImpl extends SchemaPermissions<S> {\n constructor(identityContext: IIdentityContext) {\n super(schema, identityContext);\n }\n }\n\n const Implementation = abstraction.createImplementation({\n implementation: PermissionsImpl,\n dependencies: [IdentityContext]\n });\n\n return createFeature({\n name: `${schema.prefix}:Permissions`,\n register(container) {\n container.register(Implementation).inSingletonScope();\n },\n resolve(container) {\n return { permissions: container.resolve(abstraction) };\n }\n });\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|