@easy-cms/core 0.32.0 → 0.33.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.
Files changed (3) hide show
  1. package/dist/index.d.ts +161 -5
  2. package/dist/index.js +652 -195
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -741,6 +741,137 @@ type UpdateInput<C extends Config, S extends CollectionSlug<C>> = Partial<Create
741
741
  /** Data accepted by `updateGlobal`. */
742
742
  type GlobalInput<C extends Config, S extends GlobalSlug<C>> = Partial<Simplify<FieldsInput<GlobalBySlug<C, S>['fields']> & StatusInput<GlobalBySlug<C, S>>>>;
743
743
 
744
+ /** What a role may do with a collection or global, ticked in Settings → Roles. */
745
+ declare const ROLE_OPERATIONS: readonly ["read", "create", "update", "delete", "publish"];
746
+ type RoleOperation = (typeof ROLE_OPERATIONS)[number];
747
+ /**
748
+ * Stored in a role's `permissions`. Anything not listed is not allowed. A slug listed with no
749
+ * operations has been looked at and given nothing (it is not "new" in Settings → Roles).
750
+ */
751
+ interface RolePermissions {
752
+ readonly collections?: Readonly<Record<string, readonly RoleOperation[]>>;
753
+ readonly globals?: Readonly<Record<string, readonly RoleOperation[]>>;
754
+ /** Admin pages: `status`, `deliveries`, `page:<path>` (`admin.pages`), `widget:<tag>` (`admin.dashboard`). */
755
+ readonly admin?: readonly string[];
756
+ }
757
+ /** One role as Settings → Roles shows it (`GET <api>/admin/roles`). */
758
+ interface AdminRole {
759
+ id: ID;
760
+ key: string;
761
+ /** The name shown in the admin; empty for roles from the config that were not renamed. */
762
+ name: string;
763
+ /** From `auth.roles`: can't be deleted. */
764
+ system: boolean;
765
+ /** Users with this role. */
766
+ users: number;
767
+ permissions: RolePermissions;
768
+ updatedAt: string;
769
+ }
770
+ /** A row of the permissions table. */
771
+ interface AdminRoleTarget {
772
+ slug: string;
773
+ /** Operations that make sense here (`publish` with drafts). */
774
+ ops: RoleOperation[];
775
+ /** No role has been given anything here yet (added to the config since). */
776
+ new: boolean;
777
+ }
778
+ /** A page or dashboard panel that can be given to roles. */
779
+ interface AdminRoleView {
780
+ id: string;
781
+ /** For plugin pages and panels; the admin names `status` and `deliveries` itself. */
782
+ label?: Label;
783
+ }
784
+ /** Settings → Roles (`GET <api>/admin/roles`). */
785
+ interface AdminRoles {
786
+ roles: AdminRole[];
787
+ collections: (AdminRoleTarget & {
788
+ /** Collections its relationship and upload fields point to. */
789
+ references: string[];
790
+ })[];
791
+ globals: AdminRoleTarget[];
792
+ views: AdminRoleView[];
793
+ }
794
+ /** One change to a role (`GET <api>/admin/roles/:id/history`). */
795
+ interface AdminRoleChange {
796
+ id: ID;
797
+ /** Email of who saved it, or `null` when it was the system (first start). */
798
+ author: string | null;
799
+ createdAt: string;
800
+ name: string;
801
+ permissions: RolePermissions;
802
+ }
803
+ /**
804
+ * Roles and their permissions (`auth.rbac`), on top of access rules: an operation is allowed
805
+ * when both allow it. Admins may do everything; requests that are not logged in are left to
806
+ * access rules alone.
807
+ */
808
+ declare class Roles {
809
+ private readonly config;
810
+ private readonly db;
811
+ readonly enabled: boolean;
812
+ private readonly versions;
813
+ private cache;
814
+ private synced;
815
+ constructor(config: ResolvedConfig, db: Database);
816
+ /**
817
+ * Whether the user's role allows an operation: `true`, `false`, or for their own account
818
+ * (users without read or update on `users`) a constraint to it.
819
+ */
820
+ allows(user: AuthUser | null, target: {
821
+ collection: string;
822
+ } | {
823
+ global: string;
824
+ }, operation: RoleOperation): Promise<boolean | Where>;
825
+ /**
826
+ * Whether the user may open an admin page: admins always; with roles, those whose role has
827
+ * it; without roles, nobody else (`status`, `deliveries`) or everybody (plugin pages).
828
+ */
829
+ canView(user: AuthUser, id: string): Promise<boolean>;
830
+ /** Forgets cached permissions, after a role changed. */
831
+ invalidate(): void;
832
+ /**
833
+ * Adds the roles of `auth.roles` that are missing; on the first start, gives them everything.
834
+ * Runs once, on first use (not on startup: `easy-cms migrate` opens the CMS before the table exists).
835
+ */
836
+ sync(): Promise<void>;
837
+ private addMissing;
838
+ /** Whether a role exists (users can only be given existing roles). */
839
+ exists(key: string): Promise<boolean>;
840
+ /** Roles a user can be given, those of `auth.roles` first; `name` may be empty. */
841
+ options(): Promise<{
842
+ key: string;
843
+ name: string;
844
+ }[]>;
845
+ list(): Promise<AdminRoles>;
846
+ create(input: {
847
+ key?: unknown;
848
+ name?: unknown;
849
+ permissions?: unknown;
850
+ }, author: AuthUser): Promise<AdminRole>;
851
+ update(id: ID, input: {
852
+ name?: unknown;
853
+ permissions?: unknown;
854
+ }, author: AuthUser): Promise<AdminRole>;
855
+ delete(id: ID): Promise<void>;
856
+ history(id: ID): Promise<AdminRoleChange[]>;
857
+ /** Pages and panels roles can be given. */
858
+ private views;
859
+ /** Every collection and global, and the plugin pages and panels: what roles had before roles. */
860
+ private everything;
861
+ /** Keeps only known collections, globals, operations and pages; `read` comes with the others. */
862
+ private clean;
863
+ private cleanName;
864
+ private permissionsOf;
865
+ private load;
866
+ private rows;
867
+ private row;
868
+ private users;
869
+ private insert;
870
+ /** Keeps the role as saved, for its history. */
871
+ private record;
872
+ private toRole;
873
+ }
874
+
744
875
  interface StoredFile {
745
876
  readonly body: Uint8Array;
746
877
  readonly size: number;
@@ -882,6 +1013,8 @@ declare class EasyCMS<C extends Config = Config> {
882
1013
  readonly storage: StorageAdapter;
883
1014
  /** Project root: relative paths in the config (e.g. `admin.modules`) start here. */
884
1015
  readonly cwd: string;
1016
+ /** Roles and their permissions (`auth.rbac`, Settings → Roles). */
1017
+ readonly roles: Roles;
885
1018
  private readonly versions;
886
1019
  private readonly webhooks;
887
1020
  private readonly mailer;
@@ -1101,8 +1234,11 @@ declare class EasyCMS<C extends Config = Config> {
1101
1234
  /** @internal */
1102
1235
  collection(slug: string): CollectionConfig;
1103
1236
  private global;
1104
- /** Refuses what a request's API key does not allow (see `ApiKeyPermissions`). */
1105
- private checkKey;
1237
+ /**
1238
+ * Refuses what a request's API key (see `ApiKeyPermissions`) or the user's role (`auth.rbac`)
1239
+ * does not allow. Returns a constraint when the role allows only the user's own account.
1240
+ */
1241
+ private checkGrant;
1106
1242
  /** The query constraint read access adds, or `undefined` when there is none. Throws when denied. */
1107
1243
  private readWhere;
1108
1244
  private checkDocumentAccess;
@@ -1603,6 +1739,8 @@ interface DashboardWidget {
1603
1739
  readonly component: AdminComponent;
1604
1740
  /** `half` (default): the side column, beside drafts and recent edits; `full`: below both. */
1605
1741
  readonly width?: 'half' | 'full';
1742
+ /** Its name in Settings → Roles (`auth.rbac`). Default: the component's tag. */
1743
+ readonly label?: Label;
1606
1744
  /** Who sees it. */
1607
1745
  readonly access?: AdminViewAccess;
1608
1746
  }
@@ -1679,8 +1817,16 @@ interface RoutesConfig {
1679
1817
  readonly api?: string;
1680
1818
  }
1681
1819
  interface AuthConfig {
1682
- /** Roles a user can have. Must include `admin`. Default `['admin', 'editor']`. */
1820
+ /**
1821
+ * Roles a user can have. Must include `admin`. Default `['admin', 'editor']`. With `rbac`, these
1822
+ * are the roles that always exist; admins can add more in Settings → Roles.
1823
+ */
1683
1824
  readonly roles?: readonly string[];
1825
+ /**
1826
+ * Roles and their permissions from the admin (Settings → Roles): admins tick what each role
1827
+ * may do with each collection, global and admin page, on top of access rules. Default `false`.
1828
+ */
1829
+ readonly rbac?: boolean;
1684
1830
  /** Session lifetime in seconds. Default 7 days. */
1685
1831
  readonly tokenExpiration?: number;
1686
1832
  /** Failed logins allowed per email (and IP) within `lockWindow`. Default 5. */
@@ -2279,6 +2425,7 @@ interface AdminCollection {
2279
2425
  create: boolean;
2280
2426
  update: boolean;
2281
2427
  delete: boolean;
2428
+ publish: boolean;
2282
2429
  };
2283
2430
  }
2284
2431
  interface AdminGlobal {
@@ -2297,6 +2444,7 @@ interface AdminGlobal {
2297
2444
  permissions: {
2298
2445
  read: boolean;
2299
2446
  update: boolean;
2447
+ publish: boolean;
2300
2448
  };
2301
2449
  }
2302
2450
  /** A page of its own in the admin (`admin.pages`) that this user may open. */
@@ -2330,11 +2478,19 @@ interface AdminSchema {
2330
2478
  modules: string[];
2331
2479
  /** Files can be uploaded from links (`upload.fromURL`). */
2332
2480
  uploadFromURL: boolean;
2333
- /** For admins: which saved deliveries the admin can show (webhooks, emails). */
2481
+ /** Which saved deliveries the admin can show (webhooks, emails), for users who may see them. */
2334
2482
  deliveries?: {
2335
2483
  webhook: boolean;
2336
2484
  email: boolean;
2337
2485
  };
2486
+ /** Admin pages this user may open: Settings → Backups, Email, Roles; deliveries; the status panel. */
2487
+ views: {
2488
+ status: boolean;
2489
+ deliveries: boolean;
2490
+ backups: boolean;
2491
+ email: boolean;
2492
+ roles: boolean;
2493
+ };
2338
2494
  /** Pages this user may open (`admin.pages`). */
2339
2495
  pages: AdminPageRef[];
2340
2496
  /** Dashboard panels this user may see (`admin.dashboard`). */
@@ -2433,4 +2589,4 @@ declare function validateConfig(config: Config): ConfigIssue[];
2433
2589
  /** The version of `@easy-cms/core`, set when the package is built. */
2434
2590
  declare const VERSION: string;
2435
2591
 
2436
- export { ADMIN_ICONS, API_KEYS, API_KEY_GLOBAL_OPERATIONS, API_KEY_OPERATIONS, type Access, type AccessArgs, type AccessOptions, type AdminAttention, type AdminBackup, type AdminBackups, type AdminBrand, type AdminCollection, type AdminComponent, type AdminComponentRef, type AdminConfig, type AdminDeliveries, type AdminDelivery, type AdminEmail, type AdminEmailDelivery, type AdminField, type AdminGlobal, type AdminIcon, type AdminLocale, type AdminPage, type AdminPageRef, type AdminSchema, type AdminStatus, type AdminViewAccess, type AdminWebhookDelivery, type AdminWidgetRef, type AfterChangeHook, type AfterDeleteHook, type AfterReadHook, type ApiKeyContext, type ApiKeyGlobalOperation, type ApiKeyOperation, type ApiKeyPermissions, type ArrayField, Auth, type AuthConfig, type AuthUser, BUILTIN_COLLECTIONS, type BackupState, type BackupsConfig, type BeforeChangeHook, type BeforeDeleteHook, type BeforeValidateHook, type Block, type BlocksField, type BooleanField, type BuiltinApiKeysCollection, type BuiltinMediaCollection, type BuiltinUsersCollection, type BundleHints, CONFIG_FILE_NAMES, CSRF_COOKIE, CSRF_HEADER, type CliCommand, type CollectionAccess, type CollectionAdmin, type CollectionConfig, type CollectionDocument, type CollectionHooks, type CollectionListAdmin, type CollectionSlug, type Config, ConfigError, type ConfigIssue, type ContainerAdmin, type CopyProgress, type CopyResult, type CreateEasyCMSOptions, type CreateInput, type CreateMigrationResult, type CustomField, type CustomFieldTypes, DEFAULT_ADMIN_PATH, DEFAULT_API_PATH, DEFAULT_DEPTH, DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_VERSIONS, DEFAULT_PASSWORD_EMAILS, DEFAULT_TOKEN_EXPIRATION, type DashboardWidget, type Database, type DatabaseAdapter, type DatabaseInitArgs, type DatabaseTransfer, type DateField, type DeliveryKind, type DeliveryState, type DepthOptions, type DocumentOf, EXTENSIONS, EasyCMS, EasyCMSError, type EmailAdapter, type EmailCheck, type EmailField, type EmailMessage, type EmailSetting, type Endpoint, type EndpointRequest, FIELD_TYPES, FIELD_TYPE_BASES, type Field, type FieldAccess, type FieldAccessFn, type FieldAdmin, type FieldError, type FieldType, type FieldTypeBase, type FieldTypeDefinition, type FieldTypeValidateContext, type FieldValidate, type FieldValidateContext, type FieldValue, type FieldsInput, type FieldsValue, type FilterOptions, type FilterOptionsArgs, type FindArgs, type FindOptions, ForbiddenError, type GlobalAccess, type GlobalConfig, type GlobalDocument, type GlobalHooks, type GlobalInput, type GlobalSlug, type GroupField, type ID, INTERNAL_COLLECTIONS, type ImageSize, type InferCollection, type InferGlobal, type JsonField, type Label, type LivePreview, type LoadConfigOptions, type LocalStorageOptions, type LocalizationConfig, type Logger, type LoginArgs, MAX_DEPTH, MEDIA, MIN_PASSWORD_LENGTH, MIN_SECRET_LENGTH, type MediaDocument, type MediaSize, type MigrationInfo, NotFoundError, type NumberField, type Operation, type PaginatedDocs, type PasswordEmail, type PasswordEmailArgs, type PasswordEmailFn, type PasswordLinkOptions, PayloadTooLargeError, type Plugin, type PluginInfo, type PluginTypes, type PreviewTarget, type PreviewURL, QueryError, type RawDocument, type ReadOptions, type RelationshipField, type ResolvedConfig, type RestHandler, type RestHandlerOptions, type RichTextDocument, type RichTextField, type Role, type RoutesConfig, SESSION_COOKIE, type ScheduledJob, SchemaError, type SchemaMode, type SelectField, type SelectOption, type Session, type SlugField, type SlugOf, type StorageAdapter, type StoredFile, type TextField, type TextareaField, TooManyRequestsError, type TypedPlugin, UnauthorizedError, type UpdateInput, type UpdateOptions, type UploadConfig, type UploadField, type UploadFromURLConfig, VERSION, ValidationError, type Version, type VersionSummary, type VersionsConfig, WEBHOOK_EVENTS, type WebhookConfig, type WebhookEvent, type WebhookPayload, type Where, type WhereOperators, anyone, applyDefaults, applyPlugins, configSignature, consoleEmail, consoleLogger, copyDatabase, createEasyCMS, createRestHandler, createRootEndpointHandler, defineConfig, defineFieldType, definePlugin, fillMissing, findConfigFile, generateSlugs, generateTypes, hasRows, hashPassword, imageDimensions, importConfig, isAdmin, isHasMany, isLoggedIn, keyAllows, loadConfig, localStorage, mergeForUpdate, mimeAllowed, mimeAllowedBy, parseId, populate, readCookie, resolveAdminModule, resolveConfig, rowFields, silentLogger, singularize, slugify, sniffMimeType, validateConfig, validateFields, verifyPassword, writeBackupFile };
2592
+ export { ADMIN_ICONS, API_KEYS, API_KEY_GLOBAL_OPERATIONS, API_KEY_OPERATIONS, type Access, type AccessArgs, type AccessOptions, type AdminAttention, type AdminBackup, type AdminBackups, type AdminBrand, type AdminCollection, type AdminComponent, type AdminComponentRef, type AdminConfig, type AdminDeliveries, type AdminDelivery, type AdminEmail, type AdminEmailDelivery, type AdminField, type AdminGlobal, type AdminIcon, type AdminLocale, type AdminPage, type AdminPageRef, type AdminRole, type AdminRoleChange, type AdminRoleTarget, type AdminRoleView, type AdminRoles, type AdminSchema, type AdminStatus, type AdminViewAccess, type AdminWebhookDelivery, type AdminWidgetRef, type AfterChangeHook, type AfterDeleteHook, type AfterReadHook, type ApiKeyContext, type ApiKeyGlobalOperation, type ApiKeyOperation, type ApiKeyPermissions, type ArrayField, Auth, type AuthConfig, type AuthUser, BUILTIN_COLLECTIONS, type BackupState, type BackupsConfig, type BeforeChangeHook, type BeforeDeleteHook, type BeforeValidateHook, type Block, type BlocksField, type BooleanField, type BuiltinApiKeysCollection, type BuiltinMediaCollection, type BuiltinUsersCollection, type BundleHints, CONFIG_FILE_NAMES, CSRF_COOKIE, CSRF_HEADER, type CliCommand, type CollectionAccess, type CollectionAdmin, type CollectionConfig, type CollectionDocument, type CollectionHooks, type CollectionListAdmin, type CollectionSlug, type Config, ConfigError, type ConfigIssue, type ContainerAdmin, type CopyProgress, type CopyResult, type CreateEasyCMSOptions, type CreateInput, type CreateMigrationResult, type CustomField, type CustomFieldTypes, DEFAULT_ADMIN_PATH, DEFAULT_API_PATH, DEFAULT_DEPTH, DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_VERSIONS, DEFAULT_PASSWORD_EMAILS, DEFAULT_TOKEN_EXPIRATION, type DashboardWidget, type Database, type DatabaseAdapter, type DatabaseInitArgs, type DatabaseTransfer, type DateField, type DeliveryKind, type DeliveryState, type DepthOptions, type DocumentOf, EXTENSIONS, EasyCMS, EasyCMSError, type EmailAdapter, type EmailCheck, type EmailField, type EmailMessage, type EmailSetting, type Endpoint, type EndpointRequest, FIELD_TYPES, FIELD_TYPE_BASES, type Field, type FieldAccess, type FieldAccessFn, type FieldAdmin, type FieldError, type FieldType, type FieldTypeBase, type FieldTypeDefinition, type FieldTypeValidateContext, type FieldValidate, type FieldValidateContext, type FieldValue, type FieldsInput, type FieldsValue, type FilterOptions, type FilterOptionsArgs, type FindArgs, type FindOptions, ForbiddenError, type GlobalAccess, type GlobalConfig, type GlobalDocument, type GlobalHooks, type GlobalInput, type GlobalSlug, type GroupField, type ID, INTERNAL_COLLECTIONS, type ImageSize, type InferCollection, type InferGlobal, type JsonField, type Label, type LivePreview, type LoadConfigOptions, type LocalStorageOptions, type LocalizationConfig, type Logger, type LoginArgs, MAX_DEPTH, MEDIA, MIN_PASSWORD_LENGTH, MIN_SECRET_LENGTH, type MediaDocument, type MediaSize, type MigrationInfo, NotFoundError, type NumberField, type Operation, type PaginatedDocs, type PasswordEmail, type PasswordEmailArgs, type PasswordEmailFn, type PasswordLinkOptions, PayloadTooLargeError, type Plugin, type PluginInfo, type PluginTypes, type PreviewTarget, type PreviewURL, QueryError, ROLE_OPERATIONS, type RawDocument, type ReadOptions, type RelationshipField, type ResolvedConfig, type RestHandler, type RestHandlerOptions, type RichTextDocument, type RichTextField, type Role, type RoleOperation, type RolePermissions, Roles, type RoutesConfig, SESSION_COOKIE, type ScheduledJob, SchemaError, type SchemaMode, type SelectField, type SelectOption, type Session, type SlugField, type SlugOf, type StorageAdapter, type StoredFile, type TextField, type TextareaField, TooManyRequestsError, type TypedPlugin, UnauthorizedError, type UpdateInput, type UpdateOptions, type UploadConfig, type UploadField, type UploadFromURLConfig, VERSION, ValidationError, type Version, type VersionSummary, type VersionsConfig, WEBHOOK_EVENTS, type WebhookConfig, type WebhookEvent, type WebhookPayload, type Where, type WhereOperators, anyone, applyDefaults, applyPlugins, configSignature, consoleEmail, consoleLogger, copyDatabase, createEasyCMS, createRestHandler, createRootEndpointHandler, defineConfig, defineFieldType, definePlugin, fillMissing, findConfigFile, generateSlugs, generateTypes, hasRows, hashPassword, imageDimensions, importConfig, isAdmin, isHasMany, isLoggedIn, keyAllows, loadConfig, localStorage, mergeForUpdate, mimeAllowed, mimeAllowedBy, parseId, populate, readCookie, resolveAdminModule, resolveConfig, rowFields, silentLogger, singularize, slugify, sniffMimeType, validateConfig, validateFields, verifyPassword, writeBackupFile };