@headless-lms/core 0.3.0 → 0.5.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/dist/assets/events.d.ts +24 -18
- package/dist/assets/file-urls.d.ts +11 -7
- package/dist/assets/file-urls.js +14 -4
- package/dist/assets/file-urls.js.map +1 -1
- package/dist/assets/index.d.ts +5 -4
- package/dist/assets/index.js +4 -3
- package/dist/assets/jobs.d.ts +15 -0
- package/dist/assets/jobs.js +30 -0
- package/dist/assets/jobs.js.map +1 -0
- package/dist/assets/ports.d.ts +37 -17
- package/dist/assets/service.d.ts +30 -15
- package/dist/assets/service.js +229 -59
- package/dist/assets/service.js.map +1 -1
- package/dist/automations/actions.js +2 -63
- package/dist/automations/actions.js.map +1 -1
- package/dist/automations/catalog.d.ts +1 -2
- package/dist/automations/catalog.js +137 -65
- package/dist/automations/catalog.js.map +1 -1
- package/dist/automations/community-derivations.js +20 -20
- package/dist/automations/community-derivations.js.map +1 -1
- package/dist/automations/community-mail.d.ts +36 -20
- package/dist/automations/community-mail.js +32 -24
- package/dist/automations/community-mail.js.map +1 -1
- package/dist/automations/event-permissions.d.ts +12 -0
- package/dist/automations/event-permissions.js +38 -0
- package/dist/automations/event-permissions.js.map +1 -0
- package/dist/automations/events.d.ts +0 -10
- package/dist/automations/index.d.ts +12 -4
- package/dist/automations/index.js +9 -1
- package/dist/automations/notifications/applicable.d.ts +8 -0
- package/dist/automations/notifications/applicable.js +12 -0
- package/dist/automations/notifications/applicable.js.map +1 -0
- package/dist/automations/notifications/debounce.d.ts +25 -0
- package/dist/automations/notifications/debounce.js +93 -0
- package/dist/automations/notifications/debounce.js.map +1 -0
- package/dist/automations/notifications/defaults.d.ts +8 -0
- package/dist/automations/notifications/defaults.js +346 -0
- package/dist/automations/notifications/defaults.js.map +1 -0
- package/dist/automations/notifications/delivery.d.ts +28 -0
- package/dist/automations/notifications/delivery.js +88 -0
- package/dist/automations/notifications/delivery.js.map +1 -0
- package/dist/automations/notifications/processor.d.ts +64 -0
- package/dist/automations/notifications/processor.js +270 -0
- package/dist/automations/notifications/processor.js.map +1 -0
- package/dist/automations/notifications/rules/content.d.ts +6 -0
- package/dist/automations/notifications/rules/content.js +96 -0
- package/dist/automations/notifications/rules/content.js.map +1 -0
- package/dist/automations/notifications/rules/discussion.d.ts +7 -0
- package/dist/automations/notifications/rules/discussion.js +678 -0
- package/dist/automations/notifications/rules/discussion.js.map +1 -0
- package/dist/automations/notifications/rules/entitlements.d.ts +6 -0
- package/dist/automations/notifications/rules/entitlements.js +276 -0
- package/dist/automations/notifications/rules/entitlements.js.map +1 -0
- package/dist/automations/notifications/rules/events.d.ts +9 -0
- package/dist/automations/notifications/rules/events.js +27 -0
- package/dist/automations/notifications/rules/events.js.map +1 -0
- package/dist/automations/notifications/rules/index.d.ts +6 -0
- package/dist/automations/notifications/rules/index.js +15 -0
- package/dist/automations/notifications/rules/index.js.map +1 -0
- package/dist/automations/notifications/rules/organizations.d.ts +6 -0
- package/dist/automations/notifications/rules/organizations.js +35 -0
- package/dist/automations/notifications/rules/organizations.js.map +1 -0
- package/dist/automations/notifications/rules/recipients.d.ts +32 -0
- package/dist/automations/notifications/rules/recipients.js +98 -0
- package/dist/automations/notifications/rules/recipients.js.map +1 -0
- package/dist/automations/notifications/service.d.ts +29 -0
- package/dist/automations/notifications/service.js +45 -0
- package/dist/automations/notifications/service.js.map +1 -0
- package/dist/automations/notifications/types.d.ts +7 -0
- package/dist/automations/notifications/types.js +560 -0
- package/dist/automations/notifications/types.js.map +1 -0
- package/dist/automations/ports.d.ts +134 -21
- package/dist/automations/service.d.ts +30 -30
- package/dist/automations/service.js +111 -144
- package/dist/automations/service.js.map +1 -1
- package/dist/content/event-sight.d.ts +11 -0
- package/dist/content/event-sight.js +11 -0
- package/dist/content/event-sight.js.map +1 -0
- package/dist/content/events.d.ts +437 -46
- package/dist/content/events.js +45 -1
- package/dist/content/events.js.map +1 -1
- package/dist/content/index.d.ts +8 -4
- package/dist/content/index.js +5 -1
- package/dist/content/jobs.d.ts +16 -0
- package/dist/content/jobs.js +37 -0
- package/dist/content/jobs.js.map +1 -0
- package/dist/content/model.d.ts +2 -2
- package/dist/content/notification-categories.d.ts +37 -0
- package/dist/content/notification-categories.js +73 -0
- package/dist/content/notification-categories.js.map +1 -0
- package/dist/content/ports.d.ts +132 -68
- package/dist/content/service.d.ts +100 -68
- package/dist/content/service.js +703 -146
- package/dist/content/service.js.map +1 -1
- package/dist/content/titles.d.ts +25 -0
- package/dist/content/titles.js +82 -0
- package/dist/content/titles.js.map +1 -0
- package/dist/content/types.d.ts +2 -2
- package/dist/discussion/authors.d.ts +4 -2
- package/dist/discussion/authors.js +9 -5
- package/dist/discussion/authors.js.map +1 -1
- package/dist/discussion/chats.d.ts +63 -39
- package/dist/discussion/chats.js +455 -190
- package/dist/discussion/chats.js.map +1 -1
- package/dist/discussion/digests.d.ts +24 -0
- package/dist/discussion/digests.js +104 -0
- package/dist/discussion/digests.js.map +1 -0
- package/dist/discussion/events.d.ts +227 -23
- package/dist/discussion/events.js +114 -19
- package/dist/discussion/events.js.map +1 -1
- package/dist/discussion/index.d.ts +12 -4
- package/dist/discussion/index.js +9 -2
- package/dist/discussion/jobs.d.ts +16 -0
- package/dist/discussion/jobs.js +40 -0
- package/dist/discussion/jobs.js.map +1 -0
- package/dist/discussion/live.d.ts +106 -0
- package/dist/discussion/live.js +642 -0
- package/dist/discussion/live.js.map +1 -0
- package/dist/discussion/mentions.d.ts +11 -0
- package/dist/discussion/mentions.js +35 -0
- package/dist/discussion/mentions.js.map +1 -0
- package/dist/discussion/ports.d.ts +279 -114
- package/dist/discussion/ports.js.map +1 -1
- package/dist/discussion/posts.d.ts +60 -44
- package/dist/discussion/posts.js +453 -287
- package/dist/discussion/posts.js.map +1 -1
- package/dist/discussion/rules.d.ts +18 -0
- package/dist/discussion/rules.js +22 -0
- package/dist/discussion/rules.js.map +1 -0
- package/dist/discussion/service.d.ts +50 -35
- package/dist/discussion/service.js +333 -205
- package/dist/discussion/service.js.map +1 -1
- package/dist/discussion/subscriptions.d.ts +37 -0
- package/dist/discussion/subscriptions.js +115 -0
- package/dist/discussion/subscriptions.js.map +1 -0
- package/dist/discussion/titles.d.ts +28 -0
- package/dist/discussion/titles.js +98 -0
- package/dist/discussion/titles.js.map +1 -0
- package/dist/entitlements/events.d.ts +20 -20
- package/dist/entitlements/index.d.ts +5 -4
- package/dist/entitlements/index.js +3 -2
- package/dist/entitlements/jobs.d.ts +12 -0
- package/dist/entitlements/jobs.js +18 -0
- package/dist/entitlements/jobs.js.map +1 -0
- package/dist/entitlements/model.d.ts +2 -2
- package/dist/entitlements/ports.d.ts +68 -38
- package/dist/entitlements/rules.d.ts +3 -6
- package/dist/entitlements/rules.js +5 -10
- package/dist/entitlements/rules.js.map +1 -1
- package/dist/entitlements/service.d.ts +43 -28
- package/dist/entitlements/service.js +387 -160
- package/dist/entitlements/service.js.map +1 -1
- package/dist/identity/devices.d.ts +30 -0
- package/dist/identity/devices.js +109 -0
- package/dist/identity/devices.js.map +1 -0
- package/dist/identity/index.d.ts +6 -5
- package/dist/identity/index.js +4 -3
- package/dist/identity/model.d.ts +2 -2
- package/dist/identity/notification-settings.d.ts +28 -0
- package/dist/identity/notification-settings.js +114 -0
- package/dist/identity/notification-settings.js.map +1 -0
- package/dist/identity/ports.d.ts +80 -56
- package/dist/identity/service.d.ts +8 -7
- package/dist/identity/service.js +17 -13
- package/dist/identity/service.js.map +1 -1
- package/dist/integrations/ports.d.ts +9 -8
- package/dist/integrations/service.d.ts +9 -8
- package/dist/integrations/service.js +33 -16
- package/dist/integrations/service.js.map +1 -1
- package/dist/organizations/default-roles.d.ts +22 -0
- package/dist/organizations/default-roles.js +89 -0
- package/dist/organizations/default-roles.js.map +1 -0
- package/dist/organizations/effective-permissions.d.ts +45 -0
- package/dist/organizations/effective-permissions.js +113 -0
- package/dist/organizations/effective-permissions.js.map +1 -0
- package/dist/organizations/events.d.ts +320 -181
- package/dist/organizations/events.js +90 -18
- package/dist/organizations/events.js.map +1 -1
- package/dist/organizations/index.d.ts +15 -10
- package/dist/organizations/index.js +8 -3
- package/dist/organizations/members.d.ts +66 -8
- package/dist/organizations/members.js.map +1 -1
- package/dist/organizations/notification-catalog.d.ts +31 -0
- package/dist/organizations/notification-catalog.js +32 -0
- package/dist/organizations/notification-catalog.js.map +1 -0
- package/dist/organizations/notification-categories.d.ts +34 -0
- package/dist/organizations/notification-categories.js +66 -0
- package/dist/organizations/notification-categories.js.map +1 -0
- package/dist/organizations/org-roles.d.ts +33 -0
- package/dist/organizations/org-roles.js +49 -0
- package/dist/organizations/org-roles.js.map +1 -0
- package/dist/organizations/permissions.d.ts +311 -0
- package/dist/organizations/permissions.js +327 -0
- package/dist/organizations/permissions.js.map +1 -0
- package/dist/organizations/ports.d.ts +187 -65
- package/dist/organizations/service.d.ts +104 -35
- package/dist/organizations/service.js +1247 -323
- package/dist/organizations/service.js.map +1 -1
- package/dist/organizations/testing.d.ts +18 -0
- package/dist/organizations/testing.js +37 -0
- package/dist/organizations/testing.js.map +1 -0
- package/dist/organizations/types.d.ts +5 -16
- package/dist/progress/index.d.ts +2 -2
- package/dist/progress/ports.d.ts +11 -3
- package/dist/progress/service.d.ts +6 -5
- package/dist/progress/service.js +23 -8
- package/dist/progress/service.js.map +1 -1
- package/dist/reporting/admin/index.d.ts +6 -4
- package/dist/reporting/admin/model.d.ts +36 -3
- package/dist/reporting/admin/ports.d.ts +39 -14
- package/dist/reporting/admin/service.d.ts +32 -11
- package/dist/reporting/admin/service.js +102 -18
- package/dist/reporting/admin/service.js.map +1 -1
- package/dist/reporting/events/index.d.ts +27 -0
- package/dist/reporting/events/index.js +20 -0
- package/dist/reporting/events/index.js.map +1 -0
- package/dist/reporting/member/calendar.d.ts +11 -0
- package/dist/reporting/member/calendar.js +75 -0
- package/dist/reporting/member/calendar.js.map +1 -0
- package/dist/reporting/member/index.d.ts +3 -2
- package/dist/reporting/member/model.d.ts +80 -26
- package/dist/reporting/member/ports.d.ts +50 -28
- package/dist/reporting/member/service.d.ts +81 -35
- package/dist/reporting/member/service.js +438 -145
- package/dist/reporting/member/service.js.map +1 -1
- package/dist/shared/actor.d.ts +22 -3
- package/dist/shared/errors.d.ts +15 -2
- package/dist/shared/errors.js +21 -2
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/id.d.ts +7 -0
- package/dist/shared/id.js +8 -1
- package/dist/shared/id.js.map +1 -1
- package/dist/shared/logger.d.ts +2 -1
- package/dist/shared/logger.js +10 -1
- package/dist/shared/logger.js.map +1 -1
- package/dist/shared/mailer.d.ts +11 -1
- package/dist/shared/mailer.js +32 -5
- package/dist/shared/mailer.js.map +1 -1
- package/dist/shared/notification-categories.d.ts +16 -0
- package/dist/shared/notification-categories.js +94 -0
- package/dist/shared/notification-categories.js.map +1 -0
- package/dist/shared/notification-settings.d.ts +14 -0
- package/dist/shared/notification-settings.js +61 -0
- package/dist/shared/notification-settings.js.map +1 -0
- package/dist/shared/ports.d.ts +68 -2
- package/dist/shared/settings.d.ts +2 -1
- package/dist/shared/settings.js +1 -0
- package/dist/shared/settings.js.map +1 -1
- package/dist/types/automations.d.ts +8 -2
- package/dist/types/content.d.ts +2 -2
- package/dist/types/discussion.d.ts +4 -5
- package/dist/types/email-templates.d.ts +119 -6
- package/dist/types/entitlements.d.ts +2 -2
- package/dist/types/identity.d.ts +14 -17
- package/dist/types/index.d.ts +13 -12
- package/dist/types/index.js +2 -1
- package/dist/types/notifications.d.ts +157 -0
- package/dist/types/notifications.js +1 -0
- package/dist/types/organizations.d.ts +3 -2
- package/dist/types/ports.d.ts +8 -1
- package/dist/types/ports.js +7 -1
- package/dist/types/ports.js.map +1 -0
- package/dist/types/schemas/assets.d.ts +5 -5
- package/dist/types/schemas/assets.js +4 -3
- package/dist/types/schemas/assets.js.map +1 -1
- package/dist/types/schemas/automations.d.ts +1 -10
- package/dist/types/schemas/automations.js +1 -3
- package/dist/types/schemas/automations.js.map +1 -1
- package/dist/types/schemas/content.d.ts +596 -11
- package/dist/types/schemas/content.js +225 -9
- package/dist/types/schemas/content.js.map +1 -1
- package/dist/types/schemas/discussion.d.ts +362 -66
- package/dist/types/schemas/discussion.js +123 -15
- package/dist/types/schemas/discussion.js.map +1 -1
- package/dist/types/schemas/entitlements.d.ts +14 -1
- package/dist/types/schemas/entitlements.js +11 -4
- package/dist/types/schemas/entitlements.js.map +1 -1
- package/dist/types/schemas/identity.d.ts +1 -85
- package/dist/types/schemas/identity.js +1 -42
- package/dist/types/schemas/identity.js.map +1 -1
- package/dist/types/schemas/index.d.ts +8 -7
- package/dist/types/schemas/index.js +8 -7
- package/dist/types/schemas/notifications.d.ts +96 -0
- package/dist/types/schemas/notifications.js +57 -0
- package/dist/types/schemas/notifications.js.map +1 -0
- package/dist/types/schemas/organizations.d.ts +96 -60
- package/dist/types/schemas/organizations.js +78 -27
- package/dist/types/schemas/organizations.js.map +1 -1
- package/dist/types/schemas/progress.d.ts +0 -1
- package/dist/types/schemas/progress.js +0 -1
- package/dist/types/schemas/progress.js.map +1 -1
- package/package.json +1 -1
- package/dist/automations/community-notifications.d.ts +0 -16
- package/dist/automations/community-notifications.js +0 -84
- package/dist/automations/community-notifications.js.map +0 -1
- package/dist/automations/seeds.d.ts +0 -17
- package/dist/automations/seeds.js +0 -235
- package/dist/automations/seeds.js.map +0 -1
- package/dist/identity/notifications.d.ts +0 -27
- package/dist/identity/notifications.js +0 -101
- package/dist/identity/notifications.js.map +0 -1
- package/dist/organizations/access-scopes.d.ts +0 -19
- package/dist/organizations/access-scopes.js +0 -89
- package/dist/organizations/access-scopes.js.map +0 -1
- package/dist/organizations/roles.d.ts +0 -19
- package/dist/organizations/roles.js +0 -82
- package/dist/organizations/roles.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","names":[],"sources":["../../src/organizations/permissions.ts"],"sourcesContent":["import { PERMISSION_KEYS } from '../types/schemas/organizations.js';\nimport type { Level, Permission } from '../types/index.js';\n\nexport type PermissionGroup =\n | 'organization'\n | 'people'\n | 'access'\n | 'content'\n | 'courses'\n | 'downloads'\n | 'communities'\n | 'events'\n | 'automations';\n\nexport interface PermissionDefinition {\n group: PermissionGroup;\n label: string;\n description: string;\n about: Level;\n implies?: readonly Permission[];\n}\n\nexport const PERMISSIONS = {\n 'organizations:read': {\n group: 'organization',\n label: 'See the organization',\n description: \"See the org's name, slug and general settings.\",\n about: 'org',\n },\n 'organizations:write': {\n group: 'organization',\n label: 'Edit the organization',\n description: \"Change the org's name, slug and general settings.\",\n about: 'org',\n implies: ['organizations:read'],\n },\n 'api_keys:read': {\n group: 'organization',\n label: 'See your API keys',\n description: 'List your own API keys.',\n about: 'org',\n },\n 'api_keys:write': {\n group: 'organization',\n label: 'Create API keys',\n description: 'Create your own API keys.',\n about: 'org',\n implies: ['api_keys:read'],\n },\n 'api_keys:delete': {\n group: 'organization',\n label: 'Revoke API keys',\n description: 'Revoke your own API keys.',\n about: 'org',\n implies: ['api_keys:read'],\n },\n 'notification_categories:read': {\n group: 'organization',\n label: 'See notification categories',\n description: \"See the notification types, channels and the org's categories and defaults.\",\n about: 'org',\n },\n 'notification_categories:write': {\n group: 'organization',\n label: 'Edit notification categories',\n description: \"Edit and reset the org's notification categories.\",\n about: 'org',\n implies: ['notification_categories:read'],\n },\n 'integrations:read': {\n group: 'organization',\n label: 'See integrations',\n description: 'See connected integrations.',\n about: 'org',\n },\n 'integrations:write': {\n group: 'organization',\n label: 'Manage integrations',\n description: 'Connect, configure and run actions on integrations.',\n about: 'org',\n implies: ['integrations:read'],\n },\n 'integrations:delete': {\n group: 'organization',\n label: 'Disconnect integrations',\n description: 'Disconnect integrations.',\n about: 'org',\n implies: ['integrations:read'],\n },\n 'analytics:read': {\n group: 'organization',\n label: 'See the overview',\n description: \"See the org's overview report.\",\n about: 'org',\n },\n 'people:read': {\n group: 'people',\n label: 'See people',\n description:\n \"List the org's people and pending invites, with each person's roles, and open any person's record.\",\n about: 'org',\n implies: ['progress:read'],\n },\n 'people:write': {\n group: 'people',\n label: 'Manage people',\n description:\n \"Invite people, resend and cancel invites, set a person's org role and give and remove roles on content items.\",\n about: 'org',\n implies: ['people:read'],\n },\n 'people:delete': {\n group: 'people',\n label: 'Remove people',\n description: 'Remove a person from the org.',\n about: 'org',\n implies: ['people:read'],\n },\n 'roles:read': {\n group: 'people',\n label: 'See roles',\n description: \"See the org's roles and their permissions.\",\n about: 'org',\n },\n 'roles:write': {\n group: 'people',\n label: 'Manage roles',\n description: 'Rename roles; change, reset and add roles through the API.',\n about: 'org',\n implies: ['roles:read'],\n },\n 'roles:delete': {\n group: 'people',\n label: 'Delete roles',\n description: 'Delete a role the org added.',\n about: 'org',\n implies: ['roles:read'],\n },\n 'access:read': {\n group: 'access',\n label: 'See access',\n description: \"See grants, including a community's roster of grant holders.\",\n about: 'org',\n },\n 'access:write': {\n group: 'access',\n label: 'Manage access',\n description: 'Grant, change and revoke access.',\n about: 'org',\n implies: ['access:read'],\n },\n 'bundles:read': {\n group: 'content',\n label: 'See bundles',\n description: 'See bundles and their names.',\n about: 'org',\n },\n 'bundles:write': {\n group: 'content',\n label: 'Edit bundles',\n description: 'Create and edit bundles.',\n about: 'org',\n implies: ['bundles:read'],\n },\n 'bundles:delete': {\n group: 'content',\n label: 'Delete bundles',\n description: 'Delete bundles.',\n about: 'org',\n implies: ['bundles:read'],\n },\n 'media:read': {\n group: 'content',\n label: 'See the media library',\n description: 'See the whole media library and attach any of its files.',\n about: 'org',\n },\n 'media:write': {\n group: 'content',\n label: 'Upload media',\n description: 'Upload to the media library and edit its files.',\n about: 'org',\n implies: ['media:read'],\n },\n 'media:delete': {\n group: 'content',\n label: 'Delete media',\n description: 'Delete files from the media library.',\n about: 'org',\n implies: ['media:read'],\n },\n 'courses:read': {\n group: 'courses',\n label: 'See courses',\n description:\n 'See the course, its modules and activities in the admin app; open it, its lessons, files and titles without a grant, unpublished included; be reachable for its lesson-comment mentions.',\n about: 'course',\n },\n 'courses:write': {\n group: 'courses',\n label: 'Edit courses',\n description:\n 'Edit and publish the course; add, change and delete its modules and activities; upload media for it and attach media uploaded for it. Creating a course needs it on the org.',\n about: 'course',\n implies: ['courses:read'],\n },\n 'courses:delete': {\n group: 'courses',\n label: 'Delete courses',\n description: 'Delete the course.',\n about: 'course',\n implies: ['courses:read'],\n },\n 'courses:moderate': {\n group: 'courses',\n label: 'Moderate lesson comments',\n description:\n \"See the course's lesson comments, held ones included; approve, remove, restore, reply to and resolve reports on them; be notified of reports. The holder's own lesson comments publish without review.\",\n about: 'course',\n implies: ['courses:read'],\n },\n 'progress:read': {\n group: 'courses',\n label: 'See learners and progress',\n description: \"See the course's learners, their progress and the course's analytics.\",\n about: 'course',\n },\n 'downloads:read': {\n group: 'downloads',\n label: 'See downloads',\n description:\n 'See the download in the admin app, and open it and its files without a grant, unpublished included.',\n about: 'download',\n },\n 'downloads:write': {\n group: 'downloads',\n label: 'Edit downloads',\n description:\n 'Edit and publish the download; upload files for it and attach files uploaded for it. Creating a download needs it on the org.',\n about: 'download',\n implies: ['downloads:read'],\n },\n 'downloads:delete': {\n group: 'downloads',\n label: 'Delete downloads',\n description: 'Delete the download.',\n about: 'download',\n implies: ['downloads:read'],\n },\n 'communities:read': {\n group: 'communities',\n label: 'See communities',\n description:\n 'See the community, its spaces, notification categories and analytics in the admin app; be a member of it without a grant, unpublished included, open every space in it and see its thumbnail while unpublished.',\n about: 'community',\n },\n 'communities:write': {\n group: 'communities',\n label: 'Configure communities',\n description:\n 'Configure the community, its spaces, topics, links, settings and notification categories; publish it; delete its spaces; upload media for it and attach media uploaded for it. Creating a community needs it on the org.',\n about: 'community',\n implies: ['communities:read'],\n },\n 'communities:delete': {\n group: 'communities',\n label: 'Delete communities',\n description: 'Delete the community.',\n about: 'community',\n implies: ['communities:read'],\n },\n 'communities:moderate': {\n group: 'communities',\n label: 'Moderate communities',\n description:\n \"See the review queue, pending and removed posts, held comments and their titles; open every space; approve, remove, restore, pin and lock posts and comments; turn comments and reactions on and off; delete any message, see deleted messages, read reported attachments, lock chats, see the message queue; see every space member and locked spaces' rosters; invite, add, approve, decline and remove space members; resolve reports; be notified of reviews, reports and join requests. The holder's own posts publish without review.\",\n about: 'community',\n },\n 'events:read': {\n group: 'events',\n label: 'See events',\n description:\n 'See the event in the admin app, drafts and canceled included; open it without a grant; see its attendees and analytics.',\n about: 'event',\n },\n 'events:write': {\n group: 'events',\n label: 'Edit events',\n description:\n 'Edit, publish and cancel the event; set its recording; grant and revoke it for others; upload files for it and attach, rename, reorder and remove them. Creating an event needs it on the org.',\n about: 'event',\n implies: ['events:read'],\n },\n 'events:delete': {\n group: 'events',\n label: 'Delete events',\n description: 'Delete the event.',\n about: 'event',\n implies: ['events:read'],\n },\n 'automations:read': {\n group: 'automations',\n label: 'See automations',\n description: 'See workflows, webhooks and their runs.',\n about: 'org',\n },\n 'automations:write': {\n group: 'automations',\n label: 'Edit automations',\n description: \"Create and edit workflows and webhooks, and reveal a webhook's signing secret.\",\n about: 'org',\n implies: ['automations:read'],\n },\n 'automations:delete': {\n group: 'automations',\n label: 'Delete automations',\n description: 'Delete workflows and webhooks.',\n about: 'org',\n implies: ['automations:read'],\n },\n} as const satisfies Record<Permission, PermissionDefinition>;\n\nexport const ALL_PERMISSIONS: readonly Permission[] = PERMISSION_KEYS;\n\nexport function isPermission(value: string): value is Permission {\n return (PERMISSION_KEYS as readonly string[]).includes(value);\n}\n\nexport function permissionAbout(permission: Permission): Level {\n return PERMISSIONS[permission].about;\n}\n\nexport function fitsLevels(permission: Permission, levels: readonly Level[]): boolean {\n const about = permissionAbout(permission);\n if (levels.includes('org')) {\n return true;\n }\n return about !== 'org' && levels.includes(about);\n}\n\nexport function withImplied(permissions: Iterable<Permission>): Set<Permission> {\n const out = new Set<Permission>();\n const queue = [...permissions];\n while (queue.length > 0) {\n const next = queue.pop()!;\n if (out.has(next)) {\n continue;\n }\n out.add(next);\n const def: PermissionDefinition = PERMISSIONS[next];\n for (const implied of def.implies ?? []) {\n queue.push(implied);\n }\n }\n return out;\n}\n\nexport interface PermissionListEntry extends Omit<PermissionDefinition, 'implies'> {\n key: Permission;\n implies?: Permission[];\n}\n\nexport function permissionList(): PermissionListEntry[] {\n return PERMISSION_KEYS.map((key) => {\n const { implies, ...definition }: PermissionDefinition = PERMISSIONS[key];\n return { key, ...definition, ...(implies && { implies: [...implies] }) };\n });\n}\n"],"mappings":";;AAsBA,MAAa,cAAc;CACzB,sBAAsB;EACpB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;CACT;CACA,uBAAuB;EACrB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,oBAAoB;CAChC;CACA,iBAAiB;EACf,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;CACT;CACA,kBAAkB;EAChB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,eAAe;CAC3B;CACA,mBAAmB;EACjB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,eAAe;CAC3B;CACA,gCAAgC;EAC9B,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;CACT;CACA,iCAAiC;EAC/B,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,8BAA8B;CAC1C;CACA,qBAAqB;EACnB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;CACT;CACA,sBAAsB;EACpB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,mBAAmB;CAC/B;CACA,uBAAuB;EACrB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,mBAAmB;CAC/B;CACA,kBAAkB;EAChB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;CACT;CACA,eAAe;EACb,OAAO;EACP,OAAO;EACP,aACE;EACF,OAAO;EACP,SAAS,CAAC,eAAe;CAC3B;CACA,gBAAgB;EACd,OAAO;EACP,OAAO;EACP,aACE;EACF,OAAO;EACP,SAAS,CAAC,aAAa;CACzB;CACA,iBAAiB;EACf,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,aAAa;CACzB;CACA,cAAc;EACZ,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;CACT;CACA,eAAe;EACb,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,YAAY;CACxB;CACA,gBAAgB;EACd,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,YAAY;CACxB;CACA,eAAe;EACb,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;CACT;CACA,gBAAgB;EACd,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,aAAa;CACzB;CACA,gBAAgB;EACd,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;CACT;CACA,iBAAiB;EACf,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,cAAc;CAC1B;CACA,kBAAkB;EAChB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,cAAc;CAC1B;CACA,cAAc;EACZ,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;CACT;CACA,eAAe;EACb,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,YAAY;CACxB;CACA,gBAAgB;EACd,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,YAAY;CACxB;CACA,gBAAgB;EACd,OAAO;EACP,OAAO;EACP,aACE;EACF,OAAO;CACT;CACA,iBAAiB;EACf,OAAO;EACP,OAAO;EACP,aACE;EACF,OAAO;EACP,SAAS,CAAC,cAAc;CAC1B;CACA,kBAAkB;EAChB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,cAAc;CAC1B;CACA,oBAAoB;EAClB,OAAO;EACP,OAAO;EACP,aACE;EACF,OAAO;EACP,SAAS,CAAC,cAAc;CAC1B;CACA,iBAAiB;EACf,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;CACT;CACA,kBAAkB;EAChB,OAAO;EACP,OAAO;EACP,aACE;EACF,OAAO;CACT;CACA,mBAAmB;EACjB,OAAO;EACP,OAAO;EACP,aACE;EACF,OAAO;EACP,SAAS,CAAC,gBAAgB;CAC5B;CACA,oBAAoB;EAClB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,gBAAgB;CAC5B;CACA,oBAAoB;EAClB,OAAO;EACP,OAAO;EACP,aACE;EACF,OAAO;CACT;CACA,qBAAqB;EACnB,OAAO;EACP,OAAO;EACP,aACE;EACF,OAAO;EACP,SAAS,CAAC,kBAAkB;CAC9B;CACA,sBAAsB;EACpB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,kBAAkB;CAC9B;CACA,wBAAwB;EACtB,OAAO;EACP,OAAO;EACP,aACE;EACF,OAAO;CACT;CACA,eAAe;EACb,OAAO;EACP,OAAO;EACP,aACE;EACF,OAAO;CACT;CACA,gBAAgB;EACd,OAAO;EACP,OAAO;EACP,aACE;EACF,OAAO;EACP,SAAS,CAAC,aAAa;CACzB;CACA,iBAAiB;EACf,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,aAAa;CACzB;CACA,oBAAoB;EAClB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;CACT;CACA,qBAAqB;EACnB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,kBAAkB;CAC9B;CACA,sBAAsB;EACpB,OAAO;EACP,OAAO;EACP,aAAa;EACb,OAAO;EACP,SAAS,CAAC,kBAAkB;CAC9B;AACF;AAEA,MAAa,kBAAyC;AAEtD,SAAgB,aAAa,OAAoC;CAC/D,OAAQ,gBAAsC,SAAS,KAAK;AAC9D;AAEA,SAAgB,gBAAgB,YAA+B;CAC7D,OAAO,YAAY,WAAW,CAAC;AACjC;AAEA,SAAgB,WAAW,YAAwB,QAAmC;CACpF,MAAM,QAAQ,gBAAgB,UAAU;CACxC,IAAI,OAAO,SAAS,KAAK,GACvB,OAAO;CAET,OAAO,UAAU,SAAS,OAAO,SAAS,KAAK;AACjD;AAEA,SAAgB,YAAY,aAAoD;CAC9E,MAAM,sBAAM,IAAI,IAAgB;CAChC,MAAM,QAAQ,CAAC,GAAG,WAAW;CAC7B,OAAO,MAAM,SAAS,GAAG;EACvB,MAAM,OAAO,MAAM,IAAI;EACvB,IAAI,IAAI,IAAI,IAAI,GACd;EAEF,IAAI,IAAI,IAAI;EACZ,MAAM,MAA4B,YAAY;EAC9C,KAAK,MAAM,WAAW,IAAI,WAAW,CAAC,GACpC,MAAM,KAAK,OAAO;CAEtB;CACA,OAAO;AACT;AAOA,SAAgB,iBAAwC;CACtD,OAAO,gBAAgB,KAAK,QAAQ;EAClC,MAAM,EAAE,SAAS,GAAG,eAAqC,YAAY;EACrE,OAAO;GAAE;GAAK,GAAG;GAAY,GAAI,WAAW,EAAE,SAAS,CAAC,GAAG,OAAO,EAAE;EAAG;CACzE,CAAC;AACH"}
|
|
@@ -1,44 +1,153 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ContentType } from "../types/schemas/content.js";
|
|
2
|
+
import { ApiKeySummary, ConnectedApp, CreatedApiKey } from "../types/identity.js";
|
|
3
|
+
import { AcceptInviteInput, AddOrgUserInput, CreateInviteInput, CreateOrgUserInput, Invite, NewOrganizationInput, OrgUser, OrgUserProfile, Organization, Permission, RoleAssignment, UpdateOrgUserInput } from "../types/schemas/organizations.js";
|
|
4
|
+
import "../types/index.js";
|
|
5
|
+
import { Actor, EffectivePermissions } from "../shared/actor.js";
|
|
2
6
|
import { OutboxAppender, UnitOfWork } from "../shared/ports.js";
|
|
3
|
-
import { Actor } from "../shared/actor.js";
|
|
4
|
-
import "./model.js";
|
|
5
|
-
import "./roles.js";
|
|
6
|
-
import { Member, MemberRoleChange, MembersQuery, Page } from "./members.js";
|
|
7
|
-
import { CreateOrganizationInput, ResendStudentInviteInput, UpdateOrganizationInput } from "./types.js";
|
|
8
7
|
import { AuthHeaders } from "../identity/ports.js";
|
|
9
8
|
import "../identity/index.js";
|
|
9
|
+
import { StoredOrgRole } from "./org-roles.js";
|
|
10
|
+
import { AssignmentRow } from "./effective-permissions.js";
|
|
11
|
+
import "./model.js";
|
|
12
|
+
import { AssignmentView, CreateRoleInput, InviteDetails, Member, MembersQuery, Page, RoleView, UpdateRoleInput, ViewerPermissions } from "./members.js";
|
|
13
|
+
import { PermissionListEntry } from "./permissions.js";
|
|
14
|
+
import { CreateOrganizationInput, UpdateOrganizationInput } from "./types.js";
|
|
10
15
|
//#region src/organizations/ports.d.ts
|
|
16
|
+
interface TransferOwnershipInput {
|
|
17
|
+
newOwnerOrgUserId: string;
|
|
18
|
+
previousOwnerRoleKey?: string | undefined;
|
|
19
|
+
}
|
|
20
|
+
interface CreateApiKeyInput {
|
|
21
|
+
name: string;
|
|
22
|
+
role: string;
|
|
23
|
+
expiresInDays?: number | undefined;
|
|
24
|
+
}
|
|
25
|
+
interface ApiKeyRole {
|
|
26
|
+
key: string;
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
}
|
|
30
|
+
type CallerLimit = {
|
|
31
|
+
scopes: readonly Permission[];
|
|
32
|
+
} | {
|
|
33
|
+
roleKey: string;
|
|
34
|
+
};
|
|
35
|
+
interface PlatformOrganizationInput {
|
|
36
|
+
name: string;
|
|
37
|
+
slug: string;
|
|
38
|
+
keyName?: string | undefined;
|
|
39
|
+
}
|
|
40
|
+
interface PlatformOrganization {
|
|
41
|
+
organization: AuthOrganization;
|
|
42
|
+
apiKey: CreatedApiKey;
|
|
43
|
+
}
|
|
44
|
+
interface PlatformAccount {
|
|
45
|
+
email: string;
|
|
46
|
+
name: string;
|
|
47
|
+
}
|
|
11
48
|
interface OrganizationService {
|
|
12
|
-
createOrganization(input:
|
|
13
|
-
|
|
49
|
+
createOrganization(input: NewOrganizationInput, headers: AuthHeaders): Promise<AuthOrganization>;
|
|
50
|
+
provisionOrganization(input: CreateOrganizationInput): Promise<Organization>;
|
|
51
|
+
updateOrganization(input: UpdateOrganizationInput, actor: Actor): Promise<Organization>;
|
|
14
52
|
deleteOrganization(id: string): Promise<Organization>;
|
|
15
53
|
addOrgUser(input: AddOrgUserInput): Promise<OrgUser>;
|
|
16
|
-
removeOrgUser(orgId: string, userId: string): Promise<OrgUser>;
|
|
17
|
-
updateOrgUser(orgId: string, userId: string, patch: UpdateOrgUserInput): Promise<OrgUser>;
|
|
54
|
+
removeOrgUser(orgId: string, userId: string): Promise<OrgUser | null>;
|
|
18
55
|
getByExternalId(externalId: string): Promise<Organization | null>;
|
|
56
|
+
getBySlug(slug: string): Promise<Organization | null>;
|
|
57
|
+
getById(id: string): Promise<Organization | null>;
|
|
58
|
+
portalIdentity(id: string): Promise<Pick<Organization, 'id' | 'name' | 'slug'>>;
|
|
19
59
|
getOrgUser(orgId: string, userId: string): Promise<OrgUser | null>;
|
|
20
60
|
getOrgUserById(orgId: string, id: string): Promise<OrgUser | null>;
|
|
61
|
+
getOrgUsersByIds(orgId: string, ids: string[]): Promise<OrgUser[]>;
|
|
21
62
|
getOrgUsersForUser(userId: string): Promise<OrgUser[]>;
|
|
22
|
-
|
|
23
|
-
|
|
63
|
+
orgIds(): Promise<string[]>;
|
|
64
|
+
actorFor(orgId: string, orgUserId: string, limit?: CallerLimit): Promise<Actor | null>;
|
|
65
|
+
resolveCaller(authOrgId: string, authUserId: string, limit?: CallerLimit): Promise<ResolvedCaller | null>;
|
|
66
|
+
systemActor(orgId: string): Actor;
|
|
67
|
+
permissionsOfMany(orgId: string, orgUserIds: string[]): Promise<Map<string, EffectivePermissions>>;
|
|
68
|
+
holders(orgId: string, permission: Permission, on?: string): Promise<string[]>;
|
|
69
|
+
permissionList(): PermissionListEntry[];
|
|
70
|
+
viewerPermissions(actor: Actor): ViewerPermissions;
|
|
71
|
+
auditRoleKeys(): Promise<number>;
|
|
72
|
+
listRoles(actor: Actor): Promise<RoleView[]>;
|
|
73
|
+
getRole(key: string, actor: Actor): Promise<RoleView>;
|
|
74
|
+
updateRole(key: string, input: UpdateRoleInput, actor: Actor): Promise<RoleView>;
|
|
75
|
+
createRole(input: CreateRoleInput, actor: Actor): Promise<RoleView>;
|
|
76
|
+
resetRole(key: string, actor: Actor): Promise<RoleView>;
|
|
77
|
+
deleteRole(key: string, actor: Actor): Promise<void>;
|
|
78
|
+
listTeam(query: MembersQuery, actor: Actor): Promise<Page<Member>>;
|
|
79
|
+
listAssignments(orgUserId: string, actor: Actor): Promise<AssignmentView[]>;
|
|
80
|
+
listAssignmentsOn(contentId: string, actor: Actor): Promise<AssignmentView[]>;
|
|
81
|
+
setOrgRole(orgUserId: string, roleKey: string, actor: Actor): Promise<AssignmentView[]>;
|
|
82
|
+
assignRole(orgUserId: string, contentId: string, roleKey: string, actor: Actor): Promise<AssignmentView[]>;
|
|
83
|
+
unassignRole(orgUserId: string, contentId: string, actor: Actor): Promise<AssignmentView[]>;
|
|
84
|
+
removePerson(orgUserId: string, actor: Actor): Promise<void>;
|
|
85
|
+
transferOwnership(input: TransferOwnershipInput, actor: Actor): Promise<void>;
|
|
86
|
+
createInvite(input: CreateInviteInput, actor: Actor, inviterUserId: string): Promise<Invite>;
|
|
87
|
+
resendInvite(orgUserId: string, actor: Actor, inviterUserId: string): Promise<void>;
|
|
88
|
+
cancelInvite(orgUserId: string, actor: Actor): Promise<void>;
|
|
24
89
|
peekInvite(token: string): Promise<Invite | null>;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
90
|
+
describeInvite(token: string): Promise<InviteDetails>;
|
|
91
|
+
acceptInvite(input: AcceptInviteInput, headers: AuthHeaders): Promise<OrgUser>;
|
|
92
|
+
listApiKeys(actor: Actor): Promise<ApiKeySummary[]>;
|
|
93
|
+
listApiKeyRoles(actor: Actor): Promise<ApiKeyRole[]>;
|
|
94
|
+
createApiKey(input: CreateApiKeyInput, actor: Actor): Promise<CreatedApiKey>;
|
|
95
|
+
deleteApiKey(keyId: string, actor: Actor): Promise<void>;
|
|
96
|
+
listConnectedApps(actor: Actor): Promise<ConnectedApp[]>;
|
|
97
|
+
revokeConnectedApp(clientId: string, actor: Actor): Promise<void>;
|
|
98
|
+
createPlatformOrganization(input: PlatformOrganizationInput): Promise<PlatformOrganization>;
|
|
99
|
+
createPlatformApiKey(orgId: string, name: string): Promise<CreatedApiKey>;
|
|
100
|
+
isPlatformAccount(email: string): boolean;
|
|
101
|
+
}
|
|
102
|
+
interface ActorFacts {
|
|
103
|
+
orgUserId: string;
|
|
104
|
+
status: OrgUser['status'];
|
|
105
|
+
assignments: AssignmentRow[];
|
|
106
|
+
storedRoles: StoredOrgRole[];
|
|
107
|
+
}
|
|
108
|
+
interface CallerFacts {
|
|
109
|
+
orgId: string;
|
|
110
|
+
userId: string | null;
|
|
111
|
+
orgUser: ActorFacts | null;
|
|
112
|
+
}
|
|
113
|
+
interface ResolvedCaller {
|
|
114
|
+
orgId: string;
|
|
115
|
+
userId: string | null;
|
|
116
|
+
orgUserId: string | null;
|
|
117
|
+
actor: Actor | null;
|
|
118
|
+
}
|
|
119
|
+
interface RolesRepository {
|
|
120
|
+
actorFacts(orgId: string, orgUserId: string): Promise<ActorFacts | null>;
|
|
121
|
+
callerFacts(authOrgId: string, authUserId: string): Promise<CallerFacts | null>;
|
|
122
|
+
storedRoles(orgId: string): Promise<StoredOrgRole[]>;
|
|
123
|
+
saveStoredRole(orgId: string, role: StoredOrgRole): Promise<void>;
|
|
124
|
+
deleteStoredRole(orgId: string, key: string): Promise<boolean>;
|
|
125
|
+
assignmentsOf(orgId: string, orgUserId: string): Promise<RoleAssignment[]>;
|
|
126
|
+
assignmentsOfMany(orgId: string, orgUserIds: string[]): Promise<Map<string, AssignmentRow[]>>;
|
|
127
|
+
assignmentsOn(orgId: string, contentId: string): Promise<RoleAssignment[]>;
|
|
128
|
+
holdersOf(orgId: string, roleKeys: string[], contentId?: string): Promise<string[]>;
|
|
129
|
+
setOrgRole(orgId: string, orgUserId: string, roleKey: string | null, assignedBy: string): Promise<void>;
|
|
130
|
+
setItemRole(orgId: string, orgUserId: string, contentId: string, contentType: ContentType, roleKey: string, assignedBy: string): Promise<void>;
|
|
131
|
+
removeItemRole(orgId: string, orgUserId: string, contentId: string): Promise<RoleAssignment | null>;
|
|
132
|
+
countHolders(orgId: string, roleKey: string, contentType?: ContentType | 'org'): Promise<number>;
|
|
133
|
+
holderCounts(orgId: string): Promise<Record<string, number>>;
|
|
134
|
+
contentTypeOf(orgId: string, contentId: string): Promise<ContentType | null>;
|
|
135
|
+
ownerOrgUserId(orgId: string): Promise<string | null>;
|
|
136
|
+
roleKeyUsage(): Promise<{
|
|
137
|
+
orgId: string;
|
|
138
|
+
roleKey: string;
|
|
139
|
+
level: string;
|
|
140
|
+
count: number;
|
|
141
|
+
stored: boolean;
|
|
142
|
+
}[]>;
|
|
143
|
+
lock(keys: string[]): Promise<void>;
|
|
33
144
|
}
|
|
34
|
-
/** Atomic write scope: tx-bound repo + outbox appender, one transaction. */
|
|
35
145
|
interface OrganizationsWriteScope {
|
|
36
146
|
organizations: OrganizationsRepository;
|
|
147
|
+
roles: RolesRepository;
|
|
37
148
|
outbox: OutboxAppender;
|
|
38
149
|
}
|
|
39
150
|
type OrganizationsUnitOfWork = UnitOfWork<OrganizationsWriteScope>;
|
|
40
|
-
/** Repo-facing write shape for a new org row. The service mints the id and
|
|
41
|
-
* resolves the defaults, so nothing is optional by the time it lands here. */
|
|
42
151
|
interface NewOrganizationRow {
|
|
43
152
|
id: string;
|
|
44
153
|
externalId?: string | null;
|
|
@@ -46,10 +155,9 @@ interface NewOrganizationRow {
|
|
|
46
155
|
slug: string;
|
|
47
156
|
ownerId: string;
|
|
48
157
|
}
|
|
49
|
-
/** Repo-facing write shape for a freshly minted invite. */
|
|
50
158
|
interface NewInviteRow {
|
|
51
159
|
email: string;
|
|
52
|
-
|
|
160
|
+
roleKey: string;
|
|
53
161
|
invitedBy: string;
|
|
54
162
|
tokenHash: string;
|
|
55
163
|
expiresAt: Date;
|
|
@@ -57,70 +165,84 @@ interface NewInviteRow {
|
|
|
57
165
|
interface OrganizationsRepository {
|
|
58
166
|
create(input: NewOrganizationRow): Promise<Organization>;
|
|
59
167
|
update(id: string, input: UpdateOrganizationInput): Promise<Organization | null>;
|
|
60
|
-
/** Drops the org row and its dependents; null when none matched. */
|
|
61
168
|
delete(id: string): Promise<Organization>;
|
|
62
169
|
findById(id: string): Promise<Organization | null>;
|
|
170
|
+
listIds(): Promise<string[]>;
|
|
63
171
|
findByExternalId(externalId: string): Promise<Organization | null>;
|
|
64
172
|
findBySlug(slug: string): Promise<Organization | null>;
|
|
65
|
-
/** Inserts a pending invite, or re-issues the org's existing pending one
|
|
66
|
-
* for this email (fresh token/expiry/role) — atomic upsert. */
|
|
67
173
|
upsertPendingInvite(orgId: string, input: NewInviteRow): Promise<Invite>;
|
|
68
174
|
setInviteStatus(orgId: string, id: string, status: string): Promise<Invite | null>;
|
|
175
|
+
setInviteRole(orgId: string, id: string, roleKey: string, invitedBy: string): Promise<Invite | null>;
|
|
69
176
|
findInviteByTokenHash(tokenHash: string): Promise<Invite | null>;
|
|
70
177
|
findPendingInvite(orgId: string, email: string): Promise<Invite | null>;
|
|
71
|
-
setInviteToken(orgId: string, id: string, tokenHash: string, expiresAt: Date): Promise<Invite | null>;
|
|
72
|
-
/** The person's row in one org. `(org_id, user_id)` is unique. */
|
|
178
|
+
setInviteToken(orgId: string, id: string, tokenHash: string, expiresAt: Date, invitedBy: string): Promise<Invite | null>;
|
|
73
179
|
findOrgUser(orgId: string, userId: string): Promise<OrgUser | null>;
|
|
74
|
-
/** Every org this person belongs to, oldest first. */
|
|
75
180
|
findOrgUsersByUser(userId: string): Promise<OrgUser[]>;
|
|
76
181
|
findOrgUserById(orgId: string, id: string): Promise<OrgUser | null>;
|
|
77
182
|
findOrgUsersByIds(orgId: string, ids: string[]): Promise<OrgUser[]>;
|
|
78
|
-
findOrgUserIdsByRole(orgId: string, roles: Role[]): Promise<string[]>;
|
|
79
|
-
/** Links a user to the org under a role. Throws ConflictError when they
|
|
80
|
-
* already hold a row there. */
|
|
81
183
|
createOrgUser(input: CreateOrgUserInput): Promise<OrgUser>;
|
|
82
184
|
updateOrgUser(orgId: string, id: string, patch: UpdateOrgUserInput): Promise<OrgUser | null>;
|
|
83
|
-
/** Every org this person is a student in — the scope of `student.linked`. */
|
|
84
|
-
findStudentOrgUsers(userId: string): Promise<OrgUser[]>;
|
|
85
|
-
/** Kills the org's pending invite for an address, if any. */
|
|
86
185
|
deleteOrgUser(orgId: string, id: string): Promise<OrgUser | null>;
|
|
87
186
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
kind: 'member' | 'invite';
|
|
91
|
-
userExternalId: string | null;
|
|
92
|
-
inviteId: string | null;
|
|
93
|
-
}
|
|
94
|
-
interface MembersRepository {
|
|
95
|
-
list(orgId: string, query: MembersQuery): Promise<Page<Member>>;
|
|
96
|
-
findByEmail(orgId: string, email: string): Promise<MemberRecord | null>;
|
|
97
|
-
findById(orgId: string, id: string): Promise<MemberRecord | null>;
|
|
187
|
+
interface GrantReader {
|
|
188
|
+
holdsAnyGrant(orgId: string, orgUserId: string): Promise<boolean>;
|
|
98
189
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
190
|
+
interface TeamRow extends OrgUserProfile {
|
|
191
|
+
status: OrgUser['status'];
|
|
192
|
+
joinedAt: Date;
|
|
193
|
+
invitedAt: Date | null;
|
|
194
|
+
orgRoleKey: string | null;
|
|
195
|
+
inviteRoleKey: string | null;
|
|
196
|
+
items: {
|
|
197
|
+
contentId: string;
|
|
198
|
+
contentType: ContentType;
|
|
199
|
+
roleKey: string;
|
|
200
|
+
}[];
|
|
105
201
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
orgId: string;
|
|
109
|
-
authOrgId: string;
|
|
110
|
-
headers: Record<string, string | string[] | undefined>;
|
|
202
|
+
interface MembersRepository {
|
|
203
|
+
teamRows(orgId: string, memberRoleKey: string): Promise<TeamRow[]>;
|
|
111
204
|
}
|
|
112
|
-
/** The provider's view of an org: what it stores itself, minus the fields only
|
|
113
|
-
* the domain row carries (`ownerId`, `externalId`, `updatedAt`). */
|
|
114
205
|
type AuthOrganization = Pick<Organization, 'id' | 'name' | 'slug' | 'createdAt'>;
|
|
115
206
|
interface OrgAdmin {
|
|
116
207
|
createOrganization(headers: AuthHeaders, input: NewOrganizationInput): Promise<AuthOrganization>;
|
|
208
|
+
createOrganizationFor(ownerExternalId: string, input: NewOrganizationInput): Promise<AuthOrganization>;
|
|
117
209
|
setActiveOrganization(headers: AuthHeaders, externalId: string): Promise<void>;
|
|
118
|
-
updateOrganization(headers: AuthHeaders, id: string, input: UpdateOrganizationInput): Promise<AuthOrganization>;
|
|
119
210
|
deleteOrganization(headers: AuthHeaders, externalId: string): Promise<void>;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
211
|
+
updateOrganization(externalId: string, input: UpdateOrganizationInput): Promise<void>;
|
|
212
|
+
grantMembership(orgExternalId: string, userExternalId: string): Promise<void>;
|
|
213
|
+
setMembershipOwner(orgExternalId: string, userExternalId: string, owner: boolean): Promise<void>;
|
|
214
|
+
removeMembership(orgExternalId: string, userExternalId: string): Promise<void>;
|
|
215
|
+
}
|
|
216
|
+
interface Accounts {
|
|
217
|
+
createAccount(input: PlatformAccount): Promise<{
|
|
218
|
+
externalId: string;
|
|
219
|
+
}>;
|
|
220
|
+
}
|
|
221
|
+
interface StoredApiKey {
|
|
222
|
+
id: string;
|
|
223
|
+
name: string | null;
|
|
224
|
+
start: string | null;
|
|
225
|
+
roleKey: string | null;
|
|
226
|
+
createdAt: Date;
|
|
227
|
+
lastUsedAt: Date | null;
|
|
228
|
+
expiresAt: Date | null;
|
|
229
|
+
}
|
|
230
|
+
interface NewApiKey {
|
|
231
|
+
name: string;
|
|
232
|
+
roleKey: string;
|
|
233
|
+
expiresInDays?: number | undefined;
|
|
234
|
+
}
|
|
235
|
+
interface ApiKeys {
|
|
236
|
+
list(orgId: string, userExternalId: string): Promise<StoredApiKey[]>;
|
|
237
|
+
create(orgId: string, userExternalId: string, input: NewApiKey): Promise<StoredApiKey & {
|
|
238
|
+
key: string;
|
|
239
|
+
}>;
|
|
240
|
+
countWithRole(orgId: string, roleKey: string): Promise<number>;
|
|
241
|
+
revoke(orgId: string, userExternalId: string, keyId: string): Promise<void>;
|
|
242
|
+
listApps(orgId: string, userExternalId: string): Promise<ConnectedApp[]>;
|
|
243
|
+
revokeApp(orgId: string, userExternalId: string, clientId: string): Promise<void>;
|
|
244
|
+
revokeAllFor(orgId: string, userExternalId: string): Promise<void>;
|
|
123
245
|
}
|
|
124
246
|
//#endregion
|
|
125
|
-
export { type AuthHeaders, AuthOrganization,
|
|
247
|
+
export { Accounts, ActorFacts, ApiKeyRole, ApiKeys, type AuthHeaders, AuthOrganization, CallerFacts, CallerLimit, CreateApiKeyInput, GrantReader, MembersRepository, NewApiKey, NewInviteRow, NewOrganizationRow, OrgAdmin, OrganizationService, OrganizationsRepository, OrganizationsUnitOfWork, OrganizationsWriteScope, PlatformAccount, PlatformOrganization, PlatformOrganizationInput, ResolvedCaller, RolesRepository, StoredApiKey, TeamRow, TransferOwnershipInput };
|
|
126
248
|
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { Logger } from "../types/ports.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ApiKeySummary, ConnectedApp, CreatedApiKey } from "../types/identity.js";
|
|
3
|
+
import { AcceptInviteInput, AddOrgUserInput, CreateInviteInput, Invite, NewOrganizationInput, OrgUser, Organization, Permission } from "../types/schemas/organizations.js";
|
|
4
|
+
import "../types/index.js";
|
|
5
|
+
import { Actor, EffectivePermissions } from "../shared/actor.js";
|
|
3
6
|
import "../shared/ports.js";
|
|
4
|
-
import {
|
|
5
|
-
import "
|
|
6
|
-
import "./roles.js";
|
|
7
|
-
import { Member, MemberRoleChange, MembersQuery, Page } from "./members.js";
|
|
8
|
-
import { CreateOrganizationInput, ResendStudentInviteInput, UpdateOrganizationInput } from "./types.js";
|
|
9
|
-
import { IdentityService } from "../identity/ports.js";
|
|
7
|
+
import { AssetFiles } from "../assets/ports.js";
|
|
8
|
+
import "../assets/index.js";
|
|
10
9
|
import { Mailer } from "../shared/mailer.js";
|
|
10
|
+
import { AuthHeaders, IdentityService, SessionAdmin } from "../identity/ports.js";
|
|
11
11
|
import "../identity/index.js";
|
|
12
|
-
import {
|
|
12
|
+
import { RoleDefinition } from "./default-roles.js";
|
|
13
|
+
import "./model.js";
|
|
14
|
+
import { AssignmentView, CreateRoleInput, InviteDetails, Member, MembersQuery, Page, RoleView, UpdateRoleInput, ViewerPermissions } from "./members.js";
|
|
15
|
+
import { PermissionListEntry } from "./permissions.js";
|
|
16
|
+
import { CreateOrganizationInput, UpdateOrganizationInput } from "./types.js";
|
|
17
|
+
import { Accounts, ApiKeyRole, ApiKeys, AuthOrganization, CallerLimit, CreateApiKeyInput, GrantReader, MembersRepository, OrgAdmin, OrganizationService, OrganizationsRepository, OrganizationsUnitOfWork, PlatformAccount, PlatformOrganization, PlatformOrganizationInput, ResolvedCaller, RolesRepository, TransferOwnershipInput } from "./ports.js";
|
|
13
18
|
//#region src/organizations/service.d.ts
|
|
14
19
|
interface InviteUrls {
|
|
15
20
|
studentPortalUrl: string;
|
|
@@ -17,55 +22,119 @@ interface InviteUrls {
|
|
|
17
22
|
}
|
|
18
23
|
type OrganizationServiceParams = {
|
|
19
24
|
repo: OrganizationsRepository;
|
|
25
|
+
roles: RolesRepository;
|
|
20
26
|
membersRepo: MembersRepository;
|
|
21
27
|
people: IdentityService;
|
|
28
|
+
images: Pick<AssetFiles, 'syncPublicImage'>;
|
|
22
29
|
uow: OrganizationsUnitOfWork;
|
|
23
30
|
orgAdmin: () => OrgAdmin;
|
|
31
|
+
sessions: () => SessionAdmin;
|
|
32
|
+
apiKeys?: () => ApiKeys;
|
|
33
|
+
accounts?: () => Accounts;
|
|
34
|
+
platform?: PlatformAccount;
|
|
35
|
+
grants?: () => GrantReader;
|
|
36
|
+
defaultRoles?: readonly RoleDefinition[];
|
|
24
37
|
logger?: Logger;
|
|
25
38
|
mailer?: Pick<Mailer, 'send'>;
|
|
26
39
|
inviteUrls?: InviteUrls;
|
|
27
40
|
};
|
|
28
41
|
declare class OrganizationServiceImpl implements OrganizationService {
|
|
29
42
|
private readonly repo;
|
|
43
|
+
private readonly roles;
|
|
30
44
|
private readonly membersRepo;
|
|
31
45
|
private readonly people;
|
|
46
|
+
private readonly images;
|
|
32
47
|
private readonly uow;
|
|
33
48
|
private readonly orgAdmin;
|
|
49
|
+
private readonly sessions;
|
|
50
|
+
private readonly apiKeysPort?;
|
|
51
|
+
private readonly accountsPort?;
|
|
52
|
+
private readonly platform?;
|
|
53
|
+
private readonly grants?;
|
|
54
|
+
private readonly catalog;
|
|
34
55
|
private readonly logger;
|
|
35
56
|
private readonly mailer?;
|
|
36
57
|
private readonly inviteUrls?;
|
|
37
|
-
private readonly memberWrites;
|
|
38
58
|
constructor(params: OrganizationServiceParams);
|
|
39
|
-
createOrganization(input:
|
|
40
|
-
|
|
59
|
+
createOrganization(input: NewOrganizationInput, headers: AuthHeaders): Promise<AuthOrganization>;
|
|
60
|
+
provisionOrganization(input: CreateOrganizationInput): Promise<Organization>;
|
|
61
|
+
updateOrganization(input: UpdateOrganizationInput, actor: Actor): Promise<Organization>;
|
|
41
62
|
deleteOrganization(id: string): Promise<Organization>;
|
|
42
|
-
addOrgUser({ orgId, userId
|
|
43
|
-
removeOrgUser(orgId: string, userId: string): Promise<OrgUser>;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
acceptInvite(input: AcceptInviteInput): Promise<OrgUser>;
|
|
49
|
-
private acceptStudentInvite;
|
|
50
|
-
private acceptStaffInvite;
|
|
51
|
-
getOrgUserById(orgId: string, id: string): Promise<OrgUser | null>;
|
|
63
|
+
addOrgUser({ orgId, userId }: AddOrgUserInput): Promise<OrgUser>;
|
|
64
|
+
removeOrgUser(orgId: string, userId: string): Promise<OrgUser | null>;
|
|
65
|
+
getByExternalId(externalId: string): Promise<Organization | null>;
|
|
66
|
+
getBySlug(slug: string): Promise<Organization | null>;
|
|
67
|
+
getById(id: string): Promise<Organization | null>;
|
|
68
|
+
portalIdentity(id: string): Promise<Pick<Organization, 'id' | 'name' | 'slug'>>;
|
|
52
69
|
getOrgUser(orgId: string, userId: string): Promise<OrgUser | null>;
|
|
53
|
-
|
|
70
|
+
getOrgUserById(orgId: string, id: string): Promise<OrgUser | null>;
|
|
71
|
+
getOrgUsersByIds(orgId: string, ids: string[]): Promise<OrgUser[]>;
|
|
54
72
|
getOrgUsersForUser(userId: string): Promise<OrgUser[]>;
|
|
55
|
-
|
|
73
|
+
orgIds(): Promise<string[]>;
|
|
74
|
+
actorFor(orgId: string, orgUserId: string, limit?: CallerLimit): Promise<Actor | null>;
|
|
75
|
+
resolveCaller(authOrgId: string, authUserId: string, limit?: CallerLimit): Promise<ResolvedCaller | null>;
|
|
76
|
+
systemActor(orgId: string): Actor;
|
|
77
|
+
permissionsOfMany(orgId: string, orgUserIds: string[]): Promise<Map<string, EffectivePermissions>>;
|
|
78
|
+
holders(orgId: string, permission: Permission, on?: string): Promise<string[]>;
|
|
79
|
+
permissionList(): PermissionListEntry[];
|
|
80
|
+
viewerPermissions(actor: Actor): ViewerPermissions;
|
|
81
|
+
auditRoleKeys(): Promise<number>;
|
|
82
|
+
listRoles(actor: Actor): Promise<RoleView[]>;
|
|
83
|
+
getRole(key: string, actor: Actor): Promise<RoleView>;
|
|
84
|
+
updateRole(key: string, input: UpdateRoleInput, actor: Actor): Promise<RoleView>;
|
|
85
|
+
createRole(input: CreateRoleInput, actor: Actor): Promise<RoleView>;
|
|
86
|
+
resetRole(key: string, actor: Actor): Promise<RoleView>;
|
|
87
|
+
deleteRole(key: string, actor: Actor): Promise<void>;
|
|
88
|
+
listTeam(query: MembersQuery, actor: Actor): Promise<Page<Member>>;
|
|
89
|
+
listAssignments(orgUserId: string, actor: Actor): Promise<AssignmentView[]>;
|
|
90
|
+
listAssignmentsOn(contentId: string, actor: Actor): Promise<AssignmentView[]>;
|
|
91
|
+
setOrgRole(orgUserId: string, roleKey: string, actor: Actor): Promise<AssignmentView[]>;
|
|
92
|
+
assignRole(orgUserId: string, contentId: string, roleKey: string, actor: Actor): Promise<AssignmentView[]>;
|
|
93
|
+
unassignRole(orgUserId: string, contentId: string, actor: Actor): Promise<AssignmentView[]>;
|
|
94
|
+
removePerson(orgUserId: string, actor: Actor): Promise<void>;
|
|
95
|
+
transferOwnership(input: TransferOwnershipInput, actor: Actor): Promise<void>;
|
|
96
|
+
createInvite(input: CreateInviteInput, actor: Actor, inviterUserId: string): Promise<Invite>;
|
|
97
|
+
resendInvite(orgUserId: string, actor: Actor, inviterUserId: string): Promise<void>;
|
|
98
|
+
cancelInvite(orgUserId: string, actor: Actor): Promise<void>;
|
|
99
|
+
peekInvite(token: string): Promise<Invite | null>;
|
|
100
|
+
describeInvite(token: string): Promise<InviteDetails>;
|
|
101
|
+
acceptInvite(input: AcceptInviteInput, headers: AuthHeaders): Promise<OrgUser>;
|
|
102
|
+
private checkAcceptance;
|
|
103
|
+
listApiKeys(actor: Actor): Promise<ApiKeySummary[]>;
|
|
104
|
+
listApiKeyRoles(actor: Actor): Promise<ApiKeyRole[]>;
|
|
105
|
+
createApiKey(input: CreateApiKeyInput, actor: Actor): Promise<CreatedApiKey>;
|
|
106
|
+
deleteApiKey(keyId: string, actor: Actor): Promise<void>;
|
|
107
|
+
listConnectedApps(actor: Actor): Promise<ConnectedApp[]>;
|
|
108
|
+
revokeConnectedApp(clientId: string, actor: Actor): Promise<void>;
|
|
109
|
+
createPlatformOrganization(input: PlatformOrganizationInput): Promise<PlatformOrganization>;
|
|
110
|
+
createPlatformApiKey(orgId: string, name: string): Promise<CreatedApiKey>;
|
|
111
|
+
isPlatformAccount(email: string): boolean;
|
|
112
|
+
private platformKey;
|
|
113
|
+
private platformAccountId;
|
|
114
|
+
private platformAccount;
|
|
115
|
+
private accounts;
|
|
116
|
+
private keysWithRole;
|
|
117
|
+
private cleanUpAfterRemoval;
|
|
118
|
+
private apiKeys;
|
|
119
|
+
private externalIdsOf;
|
|
120
|
+
private pendingInviteOf;
|
|
121
|
+
private deleteOrgUserRow;
|
|
122
|
+
private deleteOrgUserIn;
|
|
56
123
|
private sendInviteEmail;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
private
|
|
63
|
-
private
|
|
64
|
-
private
|
|
65
|
-
private
|
|
66
|
-
private
|
|
67
|
-
private
|
|
68
|
-
|
|
124
|
+
private toMember;
|
|
125
|
+
private assignmentViews;
|
|
126
|
+
private roleMap;
|
|
127
|
+
private resolveIn;
|
|
128
|
+
private findRole;
|
|
129
|
+
private relockedActor;
|
|
130
|
+
private itemPermissions;
|
|
131
|
+
private assertHolds;
|
|
132
|
+
private assertHoldsOn;
|
|
133
|
+
private assertNotSelf;
|
|
134
|
+
private assertUniqueName;
|
|
135
|
+
private parseLevels;
|
|
136
|
+
private assertFits;
|
|
137
|
+
private assertLevelsNotInUse;
|
|
69
138
|
}
|
|
70
139
|
//#endregion
|
|
71
140
|
export { InviteUrls, OrganizationServiceImpl, OrganizationServiceParams };
|