@zealamic/payload-auth-rbac-plugin 1.0.1 → 1.0.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.
Files changed (55) hide show
  1. package/README.md +17 -2
  2. package/dist/collections/users/index.js +11 -8
  3. package/dist/collections/users/index.js.map +1 -1
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/types.d.ts +6 -0
  7. package/dist/types.js.map +1 -1
  8. package/package.json +20 -16
  9. package/assets/cover-photo.jpg +0 -0
  10. package/docs/COLLECTIONS.md +0 -440
  11. package/docs/TRANSLATIONS.md +0 -469
  12. package/docs/UTILS.md +0 -226
  13. package/src/collections/permission-actions/default-data.ts +0 -36
  14. package/src/collections/permission-actions/index.ts +0 -144
  15. package/src/collections/permission-actions/types.ts +0 -56
  16. package/src/collections/permission-features/default-data.ts +0 -30
  17. package/src/collections/permission-features/index.ts +0 -122
  18. package/src/collections/permission-features/types.ts +0 -47
  19. package/src/collections/permissions/default-data.ts +0 -38
  20. package/src/collections/permissions/index.ts +0 -160
  21. package/src/collections/permissions/types.ts +0 -57
  22. package/src/collections/roles/default-data.ts +0 -44
  23. package/src/collections/roles/hooks/sync-permission-matrix-draft.ts +0 -73
  24. package/src/collections/roles/index.ts +0 -178
  25. package/src/collections/roles/types.ts +0 -56
  26. package/src/collections/roles-permissions/default-data.ts +0 -28
  27. package/src/collections/roles-permissions/index.ts +0 -107
  28. package/src/collections/roles-permissions/types.ts +0 -42
  29. package/src/collections/users/default-data.ts +0 -19
  30. package/src/collections/users/index.ts +0 -148
  31. package/src/collections/users/parent-path.ts +0 -310
  32. package/src/collections/users/types.ts +0 -25
  33. package/src/components/role-permission-matrix-client/default-data.ts +0 -25
  34. package/src/components/role-permission-matrix-client/index.tsx +0 -369
  35. package/src/components/role-permission-matrix-client/matrix.module.scss +0 -66
  36. package/src/components/role-permission-matrix-client/types.ts +0 -16
  37. package/src/endpoints/customEndpointHandler.ts +0 -5
  38. package/src/exports/client.ts +0 -1
  39. package/src/exports/rsc.ts +0 -0
  40. package/src/index.ts +0 -249
  41. package/src/lib/constants/general.ts +0 -1
  42. package/src/lib/constants/index.ts +0 -15
  43. package/src/lib/constants/permission-action.ts +0 -9
  44. package/src/lib/constants/permission-feature.ts +0 -4
  45. package/src/lib/constants/permission.ts +0 -4
  46. package/src/lib/constants/role.ts +0 -10
  47. package/src/lib/constants/user.ts +0 -1
  48. package/src/lib/utils/access.ts +0 -611
  49. package/src/lib/utils/data.ts +0 -7
  50. package/src/lib/utils/fields.ts +0 -62
  51. package/src/lib/utils/index.ts +0 -4
  52. package/src/lib/utils/localization.ts +0 -106
  53. package/src/styles/variables.scss +0 -1
  54. package/src/types.ts +0 -64
  55. /package/{src → dist}/general-types.d.ts +0 -0
@@ -1,44 +0,0 @@
1
- import type { RolesCollectionTranslations } from "./types.js"
2
-
3
- export const rolesDefaultTranslations: RolesCollectionTranslations = {
4
- en: {
5
- labels: {
6
- singular: "Role",
7
- plural: "Roles",
8
- },
9
- admin: {
10
- group: "System",
11
- },
12
- fields: {
13
- code: {
14
- label: "Code",
15
- placeholder: "Enter code",
16
- },
17
- name: {
18
- label: "Name",
19
- placeholder: "Enter name",
20
- },
21
- description: {
22
- label: "Description",
23
- placeholder: "Enter description",
24
- },
25
- status: {
26
- label: "Status",
27
- placeholder: "Select status",
28
- activeLabel: "Active",
29
- inactiveLabel: "Inactive",
30
- },
31
- dataScope: {
32
- label: "Data Scope",
33
- placeholder: "Select data scope",
34
- ownLabel: "Own",
35
- allLabel: "All",
36
- hierarchyLabel: "Hierarchy",
37
- },
38
- permissionMatrix: {
39
- label: "Permission Matrix",
40
- placeholder: "Select permission matrix",
41
- },
42
- },
43
- },
44
- }
@@ -1,73 +0,0 @@
1
- import type { CollectionAfterChangeHook } from "payload";
2
-
3
- type PermissionMatrixDraft = Record<string, boolean>;
4
-
5
- const isPermissionMatrixDraft = (
6
- value: unknown,
7
- ): value is PermissionMatrixDraft => {
8
- if (!value || typeof value !== "object" || Array.isArray(value)) {
9
- return false;
10
- }
11
-
12
- return Object.values(value).every((entry) => typeof entry === "boolean");
13
- };
14
-
15
- /**
16
- * Persists `permissionMatrixDraft` on the role document into `roles-permissions` rows.
17
- * RBAC checks use `roles-permissions`, not the JSON draft field.
18
- */
19
- export const syncPermissionMatrixDraftAfterChange: CollectionAfterChangeHook =
20
- async ({ doc, req }) => {
21
- if (!doc.id || !isPermissionMatrixDraft(doc.permissionMatrixDraft)) {
22
- return;
23
- }
24
-
25
- const roleID = doc.id;
26
-
27
- for (const [permissionID, enabled] of Object.entries(
28
- doc.permissionMatrixDraft,
29
- )) {
30
- if (!permissionID) {
31
- continue;
32
- }
33
-
34
- const existing = await req.payload.find({
35
- collection: "roles-permissions",
36
- depth: 0,
37
- limit: 1,
38
- req,
39
- where: {
40
- and: [
41
- { role: { equals: roleID } },
42
- { permission: { equals: permissionID } },
43
- ],
44
- },
45
- });
46
-
47
- const row = existing.docs[0];
48
-
49
- if (row?.id) {
50
- if (row.enabled === enabled) {
51
- continue;
52
- }
53
-
54
- await req.payload.update({
55
- id: row.id,
56
- collection: "roles-permissions",
57
- data: { enabled },
58
- req,
59
- });
60
- continue;
61
- }
62
-
63
- await req.payload.create({
64
- collection: "roles-permissions",
65
- data: {
66
- role: roleID,
67
- permission: permissionID,
68
- enabled,
69
- },
70
- req,
71
- });
72
- }
73
- };
@@ -1,178 +0,0 @@
1
- import type { CollectionConfig, Condition } from "payload";
2
- import { DATA_SCOPE, STATUS } from "../../lib/constants/role.js";
3
- import {
4
- getArrayOfMergedFieldAffectingData,
5
- getSuperAdminAccess,
6
- toLocaleRecord,
7
- toSelectPlaceholder,
8
- } from "../../lib/utils/index.js";
9
- import { syncPermissionMatrixDraftAfterChange } from "./hooks/sync-permission-matrix-draft.js";
10
- import type { RolesCollectionParams } from "./types.js";
11
-
12
- export const getRolesCollection = (params: RolesCollectionParams) => {
13
- const {
14
- translations = {},
15
- access = {},
16
- fields = [],
17
- labels = {},
18
- admin = {},
19
- } = params || {};
20
- const arrTranslationsKeys = Object.keys(translations);
21
- const roles: CollectionConfig = {
22
- slug: "roles",
23
- labels: {
24
- singular: toLocaleRecord(
25
- arrTranslationsKeys,
26
- (locale) => translations[locale]?.labels?.singular,
27
- ),
28
- plural: toLocaleRecord(
29
- arrTranslationsKeys,
30
- (locale) => translations[locale]?.labels?.plural,
31
- ),
32
- ...labels,
33
- },
34
- admin: {
35
- group: toLocaleRecord(
36
- arrTranslationsKeys,
37
- (locale) => translations[locale]?.admin?.group,
38
- ),
39
- useAsTitle: "name",
40
- defaultColumns: ["code", "name", "description", "status", "updatedAt"],
41
- ...admin,
42
- },
43
- access: {
44
- create: getSuperAdminAccess,
45
- update: getSuperAdminAccess,
46
- delete: getSuperAdminAccess,
47
- read: getSuperAdminAccess,
48
- readVersions: getSuperAdminAccess,
49
- unlock: getSuperAdminAccess,
50
- admin: ({ req }) => {
51
- return getSuperAdminAccess({ req });
52
- },
53
- ...access,
54
- },
55
- hooks: {
56
- afterChange: [syncPermissionMatrixDraftAfterChange],
57
- },
58
- fields: getArrayOfMergedFieldAffectingData({
59
- fields,
60
- defaultFields: [
61
- {
62
- name: "code",
63
- type: "text",
64
- required: true,
65
- unique: true,
66
- index: true,
67
- label: toLocaleRecord(
68
- arrTranslationsKeys,
69
- (locale) => translations[locale]?.fields?.code?.label,
70
- ),
71
- admin: {
72
- placeholder: toLocaleRecord(
73
- arrTranslationsKeys,
74
- (locale) => translations[locale]?.fields?.code?.placeholder,
75
- ),
76
- },
77
- },
78
- {
79
- name: "name",
80
- type: "text",
81
- required: true,
82
- label: toLocaleRecord(
83
- arrTranslationsKeys,
84
- (locale) => translations[locale]?.fields?.name?.label,
85
- ),
86
- admin: {
87
- placeholder: toLocaleRecord(
88
- arrTranslationsKeys,
89
- (locale) => translations[locale]?.fields?.name?.placeholder,
90
- ),
91
- },
92
- },
93
- {
94
- name: "description",
95
- type: "text",
96
- label: toLocaleRecord(
97
- arrTranslationsKeys,
98
- (locale) => translations[locale]?.fields?.description?.label,
99
- ),
100
- admin: {
101
- placeholder: toLocaleRecord(
102
- arrTranslationsKeys,
103
- (locale) =>
104
- translations[locale]?.fields?.description?.placeholder,
105
- ),
106
- },
107
- },
108
- {
109
- name: "status",
110
- type: "select",
111
- required: true,
112
- label: toLocaleRecord(
113
- arrTranslationsKeys,
114
- (locale) => translations[locale]?.fields?.status?.label,
115
- ),
116
- defaultValue: STATUS.ACTIVE,
117
- options: Object.values(STATUS).map((status) => ({
118
- label: toLocaleRecord(
119
- arrTranslationsKeys,
120
- (locale) =>
121
- translations[locale]?.fields?.status?.[`${status}Label`],
122
- ),
123
- value: status,
124
- })),
125
- admin: {
126
- placeholder: toSelectPlaceholder(
127
- arrTranslationsKeys,
128
- (locale) => translations[locale]?.fields?.status?.placeholder,
129
- ),
130
- },
131
- },
132
- {
133
- name: "dataScope",
134
- type: "select",
135
- required: true,
136
- label: toLocaleRecord(
137
- arrTranslationsKeys,
138
- (locale) => translations[locale]?.fields?.dataScope?.label,
139
- ),
140
- defaultValue: DATA_SCOPE.OWN,
141
- options: Object.values(DATA_SCOPE).map((dataScope) => ({
142
- label: toLocaleRecord(
143
- arrTranslationsKeys,
144
- (locale) =>
145
- translations[locale]?.fields?.dataScope?.[`${dataScope}Label`],
146
- ),
147
- value: dataScope,
148
- })),
149
- admin: {
150
- placeholder: toSelectPlaceholder(
151
- arrTranslationsKeys,
152
- (locale) => translations[locale]?.fields?.dataScope?.placeholder,
153
- ),
154
- },
155
- },
156
- {
157
- name: "permissionMatrixDraft",
158
- type: "json",
159
- label: toLocaleRecord(
160
- arrTranslationsKeys,
161
- (locale) => translations[locale]?.fields?.permissionMatrix?.label,
162
- ),
163
- admin: {
164
- components: {
165
- Field:
166
- "payload-auth-rbac-plugin/client#RolePermissionMatrixClient",
167
- },
168
- condition: ((_, __, { operation }) =>
169
- operation === "update") satisfies Condition,
170
- },
171
- },
172
- ],
173
- }),
174
- timestamps: true,
175
- };
176
-
177
- return roles;
178
- };
@@ -1,56 +0,0 @@
1
- import type { CollectionConfig, Field } from "payload"
2
- import type { DATA_SCOPE, STATUS } from "../../lib/constants/role.js"
3
-
4
- export type DataScope = (typeof DATA_SCOPE)[keyof typeof DATA_SCOPE]
5
- export type RoleStatus = (typeof STATUS)[keyof typeof STATUS]
6
-
7
- export type RolesCollectionTranslations = {
8
- [locale: string]: {
9
- labels?: {
10
- singular?: string
11
- plural?: string
12
- }
13
- admin?: {
14
- group?: string
15
- }
16
- fields?: {
17
- code?: {
18
- label?: string
19
- placeholder?: string
20
- }
21
- name?: {
22
- label?: string
23
- placeholder?: string
24
- }
25
- description?: {
26
- label?: string
27
- placeholder?: string
28
- }
29
- status?: {
30
- label?: string
31
- placeholder?: string
32
- activeLabel?: string
33
- inactiveLabel?: string
34
- }
35
- dataScope?: {
36
- label?: string
37
- placeholder?: string
38
- allLabel?: string
39
- ownLabel?: string
40
- hierarchyLabel?: string
41
- }
42
- permissionMatrix?: {
43
- label?: string
44
- placeholder?: string
45
- }
46
- }
47
- }
48
- }
49
-
50
- export type RolesCollectionParams = {
51
- translations?: RolesCollectionTranslations
52
- fields?: Field[]
53
- access?: CollectionConfig["access"]
54
- labels?: CollectionConfig["labels"]
55
- admin?: CollectionConfig["admin"]
56
- }
@@ -1,28 +0,0 @@
1
- import type { RolesPermissionsCollectionTranslations } from "./types.js";
2
-
3
- export const rolesPermissionsDefaultTranslations: RolesPermissionsCollectionTranslations =
4
- {
5
- en: {
6
- labels: {
7
- singular: "Role Permission",
8
- plural: "Role Permissions",
9
- },
10
- admin: {
11
- group: "System",
12
- },
13
- fields: {
14
- role: {
15
- label: "Role",
16
- placeholder: "Select role",
17
- },
18
- permission: {
19
- label: "Permission",
20
- placeholder: "Select permission",
21
- },
22
- enabled: {
23
- label: "Enabled",
24
- placeholder: "Check enabled",
25
- },
26
- },
27
- },
28
- };
@@ -1,107 +0,0 @@
1
- import type { CollectionConfig } from "payload";
2
- import {
3
- getArrayOfMergedFieldAffectingData,
4
- getSuperAdminAccess,
5
- toLocaleRecord,
6
- toSelectPlaceholder,
7
- } from "../../lib/utils/index.js";
8
- import type { RolesPermissionsCollectionParams } from "./types.js";
9
-
10
- export const getRolesPermissionsCollection = (
11
- params: RolesPermissionsCollectionParams,
12
- ) => {
13
- const {
14
- translations = {},
15
- access = {},
16
- fields = [],
17
- labels = {},
18
- admin = {},
19
- } = params || {};
20
- const arrTranslationsKeys = Object.keys(translations);
21
- const rolesPermissions: CollectionConfig = {
22
- slug: "roles-permissions",
23
- labels: {
24
- singular: toLocaleRecord(
25
- arrTranslationsKeys,
26
- (locale) => translations[locale]?.labels?.singular,
27
- ),
28
- plural: toLocaleRecord(
29
- arrTranslationsKeys,
30
- (locale) => translations[locale]?.labels?.plural,
31
- ),
32
- ...labels,
33
- },
34
- admin: {
35
- group: toLocaleRecord(
36
- arrTranslationsKeys,
37
- (locale) => translations[locale]?.admin?.group,
38
- ),
39
- useAsTitle: "role",
40
- defaultColumns: ["role", "permission", "enabled", "updatedAt"],
41
- hidden: true,
42
- ...admin,
43
- },
44
- access: {
45
- create: getSuperAdminAccess,
46
- update: getSuperAdminAccess,
47
- delete: getSuperAdminAccess,
48
- read: getSuperAdminAccess,
49
- readVersions: getSuperAdminAccess,
50
- unlock: getSuperAdminAccess,
51
- admin: ({ req }) => {
52
- return getSuperAdminAccess({ req });
53
- },
54
- ...access,
55
- },
56
- fields: getArrayOfMergedFieldAffectingData({
57
- fields,
58
- defaultFields: [
59
- {
60
- name: "role",
61
- type: "relationship",
62
- required: true,
63
- relationTo: "roles",
64
- label: toLocaleRecord(
65
- arrTranslationsKeys,
66
- (locale) => translations[locale]?.fields?.role?.label,
67
- ),
68
- admin: {
69
- placeholder: toSelectPlaceholder(
70
- arrTranslationsKeys,
71
- (locale) => translations[locale]?.fields?.role?.placeholder,
72
- ),
73
- },
74
- },
75
- {
76
- name: "permission",
77
- type: "relationship",
78
- relationTo: "permissions",
79
- required: true,
80
- label: toLocaleRecord(
81
- arrTranslationsKeys,
82
- (locale) => translations[locale]?.fields?.permission?.label,
83
- ),
84
- admin: {
85
- placeholder: toSelectPlaceholder(
86
- arrTranslationsKeys,
87
- (locale) => translations[locale]?.fields?.permission?.placeholder,
88
- ),
89
- },
90
- },
91
- {
92
- name: "enabled",
93
- type: "checkbox",
94
- required: false,
95
- defaultValue: true,
96
- label: toLocaleRecord(
97
- arrTranslationsKeys,
98
- (locale) => translations[locale]?.fields?.enabled?.label,
99
- ),
100
- },
101
- ],
102
- }),
103
- timestamps: true,
104
- };
105
-
106
- return rolesPermissions;
107
- };
@@ -1,42 +0,0 @@
1
- import type { CollectionConfig, Field } from "payload";
2
-
3
- export type RolesPermissionsCollectionTranslations = {
4
- [locale: string]: {
5
- labels?: {
6
- singular?: string;
7
- plural?: string;
8
- };
9
- admin?: {
10
- group?: string;
11
- };
12
- fields?: {
13
- role?: {
14
- label?: string;
15
- placeholder?: string;
16
- };
17
- permission?: {
18
- label?: string;
19
- placeholder?: string;
20
- };
21
- enabled?: {
22
- label?: string;
23
- placeholder?: string;
24
- };
25
- };
26
- };
27
- };
28
-
29
- export type RolesPermissionsCollectionParams = {
30
- translations?: RolesPermissionsCollectionTranslations;
31
- fields?: Field[];
32
- access?: CollectionConfig["access"];
33
- labels?: CollectionConfig["labels"];
34
- admin?: CollectionConfig["admin"];
35
- };
36
-
37
- export type RolePermission = {
38
- id: string | number;
39
- role?: string | number;
40
- permission?: string | number;
41
- enabled?: boolean;
42
- };
@@ -1,19 +0,0 @@
1
- import { UsersModificationTranslations } from "./types.js";
2
-
3
- export const usersDefaultTranslations: UsersModificationTranslations = {
4
- en: {
5
- fields: {
6
- isSuperAdmin: {
7
- label: "Super Admin",
8
- },
9
- roles: {
10
- label: "Roles",
11
- placeholder: "Select roles",
12
- },
13
- parent: {
14
- label: "Parent",
15
- placeholder: "Select parent",
16
- },
17
- },
18
- },
19
- };
@@ -1,148 +0,0 @@
1
- import type { Config, Field, PayloadRequest } from "payload";
2
- import {
3
- getArrayOfMergedFieldAffectingData,
4
- getPermissionAccess,
5
- toLocaleRecord,
6
- } from "../../lib/utils/index.js";
7
- import { mergeUserCollectionHooks } from "./parent-path.js";
8
- import type {
9
- UsersModificationParams,
10
- UsersModificationTranslations,
11
- } from "./types.js";
12
-
13
- const buildDefaultFields = (
14
- translations: UsersModificationTranslations,
15
- ): Field[] => {
16
- const locales = Object.keys(translations);
17
- return [
18
- {
19
- name: "isSuperAdmin",
20
- type: "checkbox",
21
- defaultValue: false,
22
- label: toLocaleRecord(
23
- locales,
24
- (locale) => translations[locale]?.fields?.isSuperAdmin?.label,
25
- ),
26
- admin: {
27
- readOnly: true,
28
- },
29
- },
30
- {
31
- name: "roles",
32
- type: "relationship",
33
- relationTo: "roles",
34
- hasMany: true,
35
- label: toLocaleRecord(
36
- locales,
37
- (locale) => translations[locale]?.fields?.roles?.label,
38
- ),
39
- },
40
- {
41
- name: "parent",
42
- type: "relationship",
43
- relationTo: "users",
44
- label: toLocaleRecord(
45
- locales,
46
- (locale) => translations[locale]?.fields?.parent?.label,
47
- ),
48
- filterOptions: ({ id }) => (id ? { id: { not_equals: id } } : true),
49
- },
50
- {
51
- name: "parentPath",
52
- type: "text",
53
- index: true,
54
- admin: {
55
- hidden: true,
56
- readOnly: true,
57
- },
58
- },
59
- ];
60
- };
61
-
62
- export const modifyUsersCollection = (params: UsersModificationParams = {}) => {
63
- const { translations = {}, fields: customFields = [] } = params;
64
-
65
- return (incomingConfig: Config): Config => {
66
- const config = { ...incomingConfig };
67
- const userSlug = config.admin?.user || "users";
68
-
69
- const customAdmin = {
70
- defaultColumns: ["email", "roles", "isSuperAdmin", "updatedAt"],
71
- useAsTitle: "email",
72
- ...config.admin,
73
- };
74
-
75
- const pluginFields = getArrayOfMergedFieldAffectingData({
76
- defaultFields: buildDefaultFields(translations),
77
- fields: customFields,
78
- });
79
-
80
- const existing = (config.collections || []).find(
81
- (c) => c.slug === userSlug,
82
- );
83
- const dataScopeOptions = {
84
- createdByField: "id",
85
- usersCollectionSlug: userSlug,
86
- } as const;
87
-
88
- const defaultAccess = {
89
- create: getPermissionAccess({
90
- featureCode: userSlug,
91
- actionCode: "create",
92
- }),
93
- update: getPermissionAccess({
94
- featureCode: userSlug,
95
- actionCode: "update",
96
- mode: "modify",
97
- collectionSlug: userSlug,
98
- options: dataScopeOptions,
99
- }),
100
- delete: getPermissionAccess({
101
- featureCode: userSlug,
102
- actionCode: "delete",
103
- mode: "modify",
104
- collectionSlug: userSlug,
105
- options: dataScopeOptions,
106
- }),
107
- read: getPermissionAccess({
108
- featureCode: userSlug,
109
- actionCode: "read",
110
- options: dataScopeOptions,
111
- }),
112
- };
113
-
114
- if (existing) {
115
- config.collections = (config.collections || []).map((collection) => {
116
- if (collection.slug !== userSlug) {
117
- return collection;
118
- }
119
- return {
120
- ...collection,
121
- fields: [...collection.fields, ...pluginFields],
122
- access: {
123
- ...defaultAccess,
124
- ...collection.access,
125
- },
126
- hooks: mergeUserCollectionHooks({
127
- existingHooks: collection.hooks,
128
- userSlug,
129
- }),
130
- };
131
- });
132
- } else {
133
- config.collections = [
134
- ...(config.collections || []),
135
- {
136
- slug: userSlug,
137
- auth: true,
138
- admin: customAdmin,
139
- fields: pluginFields,
140
- access: defaultAccess,
141
- hooks: mergeUserCollectionHooks({ userSlug }),
142
- },
143
- ];
144
- }
145
-
146
- return config;
147
- };
148
- };