@headless-lms/core 0.4.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 +27 -21
- 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 +4 -4
- package/dist/assets/index.js +3 -3
- package/dist/assets/ports.d.ts +34 -15
- package/dist/assets/service.d.ts +30 -14
- package/dist/assets/service.js +230 -56
- package/dist/assets/service.js.map +1 -1
- package/dist/automations/actions.js.map +1 -1
- package/dist/automations/catalog.js +69 -4
- package/dist/automations/catalog.js.map +1 -1
- package/dist/automations/community-derivations.js +16 -16
- package/dist/automations/community-derivations.js.map +1 -1
- package/dist/automations/community-mail.d.ts +34 -4
- package/dist/automations/community-mail.js +32 -4
- 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/index.d.ts +2 -1
- package/dist/automations/index.js +2 -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.js +1 -1
- package/dist/automations/notifications/debounce.js.map +1 -1
- package/dist/automations/notifications/defaults.js +33 -3
- package/dist/automations/notifications/defaults.js.map +1 -1
- package/dist/automations/notifications/processor.js +3 -3
- package/dist/automations/notifications/processor.js.map +1 -1
- package/dist/automations/notifications/rules/content.js +60 -3
- package/dist/automations/notifications/rules/content.js.map +1 -1
- package/dist/automations/notifications/rules/discussion.js +29 -29
- package/dist/automations/notifications/rules/discussion.js.map +1 -1
- package/dist/automations/notifications/rules/entitlements.js +36 -9
- package/dist/automations/notifications/rules/entitlements.js.map +1 -1
- 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/organizations.js +17 -10
- package/dist/automations/notifications/rules/organizations.js.map +1 -1
- package/dist/automations/notifications/rules/recipients.js +0 -1
- package/dist/automations/notifications/rules/recipients.js.map +1 -1
- package/dist/automations/notifications/service.d.ts +8 -6
- package/dist/automations/notifications/service.js +13 -13
- package/dist/automations/notifications/service.js.map +1 -1
- package/dist/automations/notifications/types.js +94 -7
- package/dist/automations/notifications/types.js.map +1 -1
- package/dist/automations/ports.d.ts +30 -31
- package/dist/automations/service.d.ts +20 -17
- package/dist/automations/service.js +91 -62
- 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 +413 -72
- package/dist/content/events.js +34 -1
- package/dist/content/events.js.map +1 -1
- package/dist/content/index.d.ts +6 -4
- package/dist/content/index.js +3 -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 +5 -4
- package/dist/content/notification-categories.js +15 -6
- package/dist/content/notification-categories.js.map +1 -1
- package/dist/content/ports.d.ts +113 -68
- package/dist/content/service.d.ts +99 -67
- package/dist/content/service.js +680 -139
- package/dist/content/service.js.map +1 -1
- package/dist/content/titles.d.ts +6 -3
- package/dist/content/titles.js +37 -24
- package/dist/content/titles.js.map +1 -1
- 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 +56 -37
- package/dist/discussion/chats.js +393 -161
- package/dist/discussion/chats.js.map +1 -1
- package/dist/discussion/events.d.ts +77 -39
- package/dist/discussion/events.js +41 -3
- package/dist/discussion/events.js.map +1 -1
- package/dist/discussion/index.d.ts +8 -5
- package/dist/discussion/index.js +5 -3
- 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.js +2 -2
- package/dist/discussion/mentions.js.map +1 -1
- package/dist/discussion/ports.d.ts +182 -100
- package/dist/discussion/ports.js.map +1 -1
- package/dist/discussion/posts.d.ts +45 -39
- package/dist/discussion/posts.js +268 -154
- 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 +37 -31
- package/dist/discussion/service.js +252 -188
- package/dist/discussion/service.js.map +1 -1
- package/dist/discussion/subscriptions.d.ts +8 -8
- package/dist/discussion/subscriptions.js +29 -13
- package/dist/discussion/subscriptions.js.map +1 -1
- package/dist/discussion/titles.d.ts +4 -2
- package/dist/discussion/titles.js +27 -13
- package/dist/discussion/titles.js.map +1 -1
- package/dist/entitlements/events.d.ts +20 -20
- package/dist/entitlements/index.d.ts +4 -4
- package/dist/entitlements/index.js +2 -2
- package/dist/entitlements/model.d.ts +2 -2
- package/dist/entitlements/ports.d.ts +65 -39
- 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 +40 -28
- package/dist/entitlements/service.js +370 -163
- package/dist/entitlements/service.js.map +1 -1
- package/dist/identity/devices.d.ts +3 -3
- package/dist/identity/devices.js +7 -5
- package/dist/identity/devices.js.map +1 -1
- package/dist/identity/events.d.ts +2 -2
- package/dist/identity/index.d.ts +2 -2
- package/dist/identity/index.js +2 -2
- package/dist/identity/notification-settings.d.ts +1 -1
- package/dist/identity/notification-settings.js +3 -2
- package/dist/identity/notification-settings.js.map +1 -1
- package/dist/identity/ports.d.ts +7 -7
- 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/events.d.ts +3 -3
- 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 +14 -10
- package/dist/organizations/index.js +7 -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 +6 -4
- package/dist/organizations/notification-categories.js +25 -10
- package/dist/organizations/notification-categories.js.map +1 -1
- 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 +184 -65
- package/dist/organizations/service.d.ts +102 -35
- package/dist/organizations/service.js +1245 -328
- 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/events.d.ts +14 -14
- 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 +26 -5
- package/dist/reporting/member/ports.d.ts +48 -29
- package/dist/reporting/member/service.d.ts +56 -29
- package/dist/reporting/member/service.js +328 -113
- package/dist/reporting/member/service.js.map +1 -1
- package/dist/shared/actor.d.ts +22 -3
- package/dist/shared/errors.d.ts +2 -1
- package/dist/shared/errors.js +3 -1
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/id.d.ts +4 -0
- package/dist/shared/id.js +4 -0
- 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/ports.d.ts +25 -5
- package/dist/types/content.d.ts +2 -2
- package/dist/types/discussion.d.ts +4 -5
- package/dist/types/email-templates.d.ts +22 -3
- package/dist/types/entitlements.d.ts +2 -2
- package/dist/types/identity.d.ts +13 -16
- package/dist/types/index.d.ts +9 -9
- package/dist/types/index.js +2 -1
- package/dist/types/notifications.d.ts +4 -4
- 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/content.d.ts +537 -13
- package/dist/types/schemas/content.js +201 -7
- package/dist/types/schemas/content.js.map +1 -1
- package/dist/types/schemas/discussion.d.ts +282 -59
- package/dist/types/schemas/discussion.js +77 -3
- 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/index.d.ts +5 -5
- package/dist/types/schemas/index.js +5 -5
- package/dist/types/schemas/notifications.d.ts +13 -12
- package/dist/types/schemas/notifications.js +3 -2
- package/dist/types/schemas/notifications.js.map +1 -1
- 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 +3 -4
- package/dist/types/schemas/progress.js +0 -1
- package/dist/types/schemas/progress.js.map +1 -1
- package/package.json +1 -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
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { PERMISSION_KEYS } from "../../types/schemas/organizations.js";
|
|
2
|
+
import { NotFoundError } from "../../shared/errors.js";
|
|
3
3
|
import { seesSpace } from "../../entitlements/rules.js";
|
|
4
|
+
import { channelOrder } from "../../shared/notification-categories.js";
|
|
5
|
+
import { eventSight } from "../../content/event-sight.js";
|
|
4
6
|
import { resolveChannels } from "../../shared/notification-settings.js";
|
|
7
|
+
import { applicableCategories } from "../../automations/notifications/applicable.js";
|
|
8
|
+
import { attendeeFace, attendeeView } from "../events/index.js";
|
|
9
|
+
import { eventCalendar } from "./calendar.js";
|
|
5
10
|
//#region src/reporting/member/service.ts
|
|
6
11
|
function refKey(ref) {
|
|
7
12
|
return `${ref.type}:${ref.id}`;
|
|
@@ -22,6 +27,19 @@ function itemView(ref, titles) {
|
|
|
22
27
|
function isActivityPublished(settings) {
|
|
23
28
|
return settings?.published !== false;
|
|
24
29
|
}
|
|
30
|
+
const READ_OF = {
|
|
31
|
+
course: "courses:read",
|
|
32
|
+
download: "downloads:read",
|
|
33
|
+
community: "communities:read",
|
|
34
|
+
event: "events:read"
|
|
35
|
+
};
|
|
36
|
+
const THUMBNAIL_OF = {
|
|
37
|
+
course: "Course thumbnail",
|
|
38
|
+
download: "Download thumbnail",
|
|
39
|
+
community: "Community thumbnail",
|
|
40
|
+
event: "Event thumbnail"
|
|
41
|
+
};
|
|
42
|
+
const EVENT_FACES = 10;
|
|
25
43
|
var MemberReportServiceImpl = class {
|
|
26
44
|
repo;
|
|
27
45
|
content;
|
|
@@ -29,12 +47,15 @@ var MemberReportServiceImpl = class {
|
|
|
29
47
|
files;
|
|
30
48
|
fileUrls;
|
|
31
49
|
access;
|
|
50
|
+
people;
|
|
32
51
|
notificationList;
|
|
33
52
|
titles;
|
|
34
53
|
subscriptions;
|
|
35
54
|
notificationCategories;
|
|
36
55
|
notificationSettings;
|
|
37
56
|
channels;
|
|
57
|
+
studentPortalUrl;
|
|
58
|
+
now;
|
|
38
59
|
constructor(params) {
|
|
39
60
|
this.repo = params.repo;
|
|
40
61
|
this.content = params.content;
|
|
@@ -42,35 +63,56 @@ var MemberReportServiceImpl = class {
|
|
|
42
63
|
this.files = params.files;
|
|
43
64
|
this.fileUrls = params.fileUrls;
|
|
44
65
|
this.access = params.access;
|
|
66
|
+
this.people = params.people;
|
|
45
67
|
this.notificationList = params.notifications;
|
|
46
68
|
this.titles = params.titles;
|
|
47
69
|
this.subscriptions = params.subscriptions;
|
|
48
70
|
this.notificationCategories = params.notificationCategories;
|
|
49
71
|
this.notificationSettings = params.notificationSettings;
|
|
50
72
|
this.channels = params.channels;
|
|
73
|
+
this.studentPortalUrl = params.studentPortalUrl.replace(/\/+$/, "");
|
|
74
|
+
this.now = params.now ?? (() => /* @__PURE__ */ new Date());
|
|
75
|
+
}
|
|
76
|
+
system(actor) {
|
|
77
|
+
return this.people.systemActor(actor.orgId);
|
|
51
78
|
}
|
|
52
|
-
|
|
53
|
-
|
|
79
|
+
viewer(actor) {
|
|
80
|
+
const role = actor.permissions.roleOn();
|
|
81
|
+
return {
|
|
82
|
+
orgUserId: actor.id,
|
|
83
|
+
orgRole: {
|
|
84
|
+
key: role.key,
|
|
85
|
+
name: role.name
|
|
86
|
+
},
|
|
87
|
+
permissions: PERMISSION_KEYS.filter((p) => actor.permissions.anywhere(p)),
|
|
88
|
+
orgPermissions: PERMISSION_KEYS.filter((p) => actor.permissions.has(p))
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async communityNotificationSettings(communityId, actor) {
|
|
92
|
+
if (!await this.access.isCommunityMember(communityId, actor)) throw new NotFoundError("Community", communityId);
|
|
93
|
+
const orgId = actor.orgId;
|
|
94
|
+
const system = this.system(actor);
|
|
54
95
|
const [list, settings, spaceIds, spaces, community] = await Promise.all([
|
|
55
|
-
this.notificationCategories.community.get(
|
|
56
|
-
this.notificationSettings.get(orgId, userId, { communityId }),
|
|
57
|
-
this.access.openSpaceIds(
|
|
58
|
-
this.content.listSpaces(
|
|
59
|
-
this.content.
|
|
96
|
+
this.notificationCategories.community.get(communityId, system),
|
|
97
|
+
this.notificationSettings.get(orgId, actor.userId, { communityId }),
|
|
98
|
+
this.access.openSpaceIds(communityId, actor),
|
|
99
|
+
this.content.listSpaces(communityId, system),
|
|
100
|
+
this.content.findCommunity(communityId, system)
|
|
60
101
|
]);
|
|
61
102
|
const open = new Set(spaceIds);
|
|
62
103
|
return {
|
|
63
104
|
communityId,
|
|
64
105
|
digest: community?.settings.digest ?? null,
|
|
65
|
-
categories: this.settingsView(list.categories, settings, spaces.filter((space) => open.has(space.id)).map((space) => ({
|
|
106
|
+
categories: this.settingsView(applicableCategories(list.categories, actor.permissions, { communityId }), settings, spaces.filter((space) => open.has(space.id)).map((space) => ({
|
|
66
107
|
spaceId: space.id,
|
|
67
108
|
name: space.name
|
|
68
109
|
})))
|
|
69
110
|
};
|
|
70
111
|
}
|
|
71
|
-
async orgNotificationSettings(
|
|
72
|
-
const
|
|
73
|
-
|
|
112
|
+
async orgNotificationSettings(actor) {
|
|
113
|
+
const orgId = actor.orgId;
|
|
114
|
+
const [list, settings] = await Promise.all([this.notificationCategories.org.get(orgId, this.system(actor)), this.notificationSettings.get(orgId, actor.userId, "org")]);
|
|
115
|
+
return { categories: this.settingsView(applicableCategories(list.categories, actor.permissions, "org"), settings, []) };
|
|
74
116
|
}
|
|
75
117
|
settingsView(categories, settings, spaces) {
|
|
76
118
|
const configured = channelOrder(this.channels.list());
|
|
@@ -97,27 +139,28 @@ var MemberReportServiceImpl = class {
|
|
|
97
139
|
return view;
|
|
98
140
|
});
|
|
99
141
|
}
|
|
100
|
-
async notifications(
|
|
101
|
-
const listed = await this.notificationList.list(
|
|
142
|
+
async notifications(filter, page, actor) {
|
|
143
|
+
const listed = await this.notificationList.list(filter, page, actor);
|
|
102
144
|
return {
|
|
103
|
-
rows: await this.describeNotifications(
|
|
145
|
+
rows: await this.describeNotifications(actor, listed.items),
|
|
104
146
|
total: listed.total,
|
|
105
147
|
page: page.page,
|
|
106
148
|
pageSize: page.pageSize,
|
|
107
149
|
unreadCount: listed.unreadCount
|
|
108
150
|
};
|
|
109
151
|
}
|
|
110
|
-
async notification(
|
|
111
|
-
const found = await this.notificationList.get(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return view
|
|
152
|
+
async notification(notificationId, actor) {
|
|
153
|
+
const found = await this.notificationList.get(notificationId, actor);
|
|
154
|
+
const [view] = found ? await this.describeNotifications(actor, [found]) : [];
|
|
155
|
+
if (!view) throw new NotFoundError("Notification", notificationId);
|
|
156
|
+
return view;
|
|
115
157
|
}
|
|
116
|
-
async notificationUnreadCounts(
|
|
117
|
-
const communityIds = await this.access.openCommunityIds(
|
|
118
|
-
return this.notificationList.unreadCounts(
|
|
158
|
+
async notificationUnreadCounts(actor) {
|
|
159
|
+
const communityIds = await this.access.openCommunityIds(actor);
|
|
160
|
+
return this.notificationList.unreadCounts(communityIds, actor);
|
|
119
161
|
}
|
|
120
|
-
async describeNotifications(
|
|
162
|
+
async describeNotifications(actor, rows) {
|
|
163
|
+
const orgId = actor.orgId;
|
|
121
164
|
const refs = rows.flatMap((row) => [
|
|
122
165
|
...row.subject ? [row.subject] : [],
|
|
123
166
|
...row.parent ? [row.parent] : [],
|
|
@@ -130,11 +173,11 @@ var MemberReportServiceImpl = class {
|
|
|
130
173
|
id: row.spaceId
|
|
131
174
|
}] : []
|
|
132
175
|
]);
|
|
133
|
-
const actorIds = [...new Set(rows.flatMap((row) => row.
|
|
176
|
+
const actorIds = [...new Set(rows.flatMap((row) => row.actorId ?? []))];
|
|
134
177
|
const [people, discussionTitles, contentTitles] = await Promise.all([
|
|
135
178
|
this.repo.people(orgId, actorIds),
|
|
136
|
-
this.titles.discussion.titlesFor(
|
|
137
|
-
this.titles.content.titlesFor(
|
|
179
|
+
this.titles.discussion.titlesFor(refs, actor),
|
|
180
|
+
this.titles.content.titlesFor(refs, actor)
|
|
138
181
|
]);
|
|
139
182
|
const titles = {
|
|
140
183
|
...contentTitles,
|
|
@@ -142,7 +185,7 @@ var MemberReportServiceImpl = class {
|
|
|
142
185
|
};
|
|
143
186
|
const personById = new Map(people.map((person) => [person.orgUserId, person]));
|
|
144
187
|
return rows.map((row) => {
|
|
145
|
-
const person = row.
|
|
188
|
+
const person = row.actorId ? personById.get(row.actorId) : void 0;
|
|
146
189
|
const community = row.communityId ? titles[`community:${row.communityId}`] : void 0;
|
|
147
190
|
const space = row.spaceId ? titles[`space:${row.spaceId}`] : void 0;
|
|
148
191
|
return {
|
|
@@ -164,7 +207,7 @@ var MemberReportServiceImpl = class {
|
|
|
164
207
|
actor: person ? {
|
|
165
208
|
orgUserId: person.orgUserId,
|
|
166
209
|
name: person.displayName,
|
|
167
|
-
imageUrl: person.imageAssetId ? this.fileUrls.
|
|
210
|
+
imageUrl: person.imageAssetId ? this.fileUrls.publicImage(orgId, person.orgUserId, person.imageAssetId) : null
|
|
168
211
|
} : null,
|
|
169
212
|
subject: itemView(row.subject, titles),
|
|
170
213
|
parent: itemView(row.parent, titles),
|
|
@@ -173,27 +216,44 @@ var MemberReportServiceImpl = class {
|
|
|
173
216
|
};
|
|
174
217
|
});
|
|
175
218
|
}
|
|
176
|
-
async
|
|
177
|
-
const
|
|
178
|
-
|
|
219
|
+
async opensCourse(courseId, actor) {
|
|
220
|
+
const reads = actor.permissions.has("courses:read", courseId);
|
|
221
|
+
if (!reads && !await this.access.hasAccess(actor.orgId, actor.id, courseId)) return null;
|
|
222
|
+
const course = await this.content.findCourse(courseId, this.system(actor));
|
|
223
|
+
return course && (reads || course.status === "published") ? course : null;
|
|
224
|
+
}
|
|
225
|
+
async opensDownload(downloadId, actor) {
|
|
226
|
+
const reads = actor.permissions.has("downloads:read", downloadId);
|
|
227
|
+
if (!reads && !await this.access.hasAccess(actor.orgId, actor.id, downloadId)) return null;
|
|
228
|
+
const download = await this.content.findDownload(downloadId, this.system(actor));
|
|
229
|
+
return download && (reads || download.status === "published") ? download : null;
|
|
179
230
|
}
|
|
180
|
-
async
|
|
181
|
-
|
|
182
|
-
const
|
|
183
|
-
return
|
|
231
|
+
async listCourses(actor) {
|
|
232
|
+
const ids = await this.access.listAccessibleContent(actor.orgId, actor.id, "course");
|
|
233
|
+
const system = this.system(actor);
|
|
234
|
+
return (await Promise.all(ids.map((id) => this.content.findCourse(id, system)))).filter((c) => c !== null && c.status === "published");
|
|
184
235
|
}
|
|
185
|
-
async
|
|
186
|
-
|
|
187
|
-
|
|
236
|
+
async requireCourse(courseId, actor) {
|
|
237
|
+
const course = await this.opensCourse(courseId, actor);
|
|
238
|
+
if (!course) throw new NotFoundError("Course", courseId);
|
|
239
|
+
return course;
|
|
188
240
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
return (await this.content.listCourseActivityViews(orgId, courseId)).filter((a) => isActivityPublished(a.settings));
|
|
241
|
+
getCourse(courseId, actor) {
|
|
242
|
+
return this.requireCourse(courseId, actor);
|
|
192
243
|
}
|
|
193
|
-
async
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
244
|
+
async listModules(courseId, actor) {
|
|
245
|
+
await this.requireCourse(courseId, actor);
|
|
246
|
+
return this.content.listCourseModules(courseId, this.system(actor));
|
|
247
|
+
}
|
|
248
|
+
async listActivities(courseId, actor) {
|
|
249
|
+
await this.requireCourse(courseId, actor);
|
|
250
|
+
return (await this.content.listCourseActivityViews(courseId, this.system(actor))).filter((a) => isActivityPublished(a.settings));
|
|
251
|
+
}
|
|
252
|
+
async courseProgress(courseId, actor) {
|
|
253
|
+
await this.requireCourse(courseId, actor);
|
|
254
|
+
const orgId = actor.orgId;
|
|
255
|
+
const ids = (await this.content.listCourseActivities(courseId, this.system(actor))).filter((a) => isActivityPublished(a.settings)).map((a) => a.id);
|
|
256
|
+
const records = await this.progress.listByTargets(orgId, actor.id, ids);
|
|
197
257
|
const activities = {};
|
|
198
258
|
const positions = {};
|
|
199
259
|
let done = 0;
|
|
@@ -204,7 +264,7 @@ var MemberReportServiceImpl = class {
|
|
|
204
264
|
if (r.position != null) positions[r.targetId] = r.position;
|
|
205
265
|
}
|
|
206
266
|
const courseRecord = await this.progress.get(orgId, {
|
|
207
|
-
orgUserId,
|
|
267
|
+
orgUserId: actor.id,
|
|
208
268
|
targetType: "course",
|
|
209
269
|
targetId: courseId
|
|
210
270
|
});
|
|
@@ -215,86 +275,236 @@ var MemberReportServiceImpl = class {
|
|
|
215
275
|
positions
|
|
216
276
|
};
|
|
217
277
|
}
|
|
218
|
-
async listDownloads(
|
|
219
|
-
const ids = await this.access.listAccessibleContent(orgId,
|
|
220
|
-
|
|
278
|
+
async listDownloads(actor) {
|
|
279
|
+
const ids = await this.access.listAccessibleContent(actor.orgId, actor.id, "download");
|
|
280
|
+
const system = this.system(actor);
|
|
281
|
+
return (await Promise.all(ids.map((id) => this.content.findDownload(id, system)))).filter((d) => d !== null && d.status === "published");
|
|
221
282
|
}
|
|
222
|
-
async getDownload(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (!download || download.status !== "published") return null;
|
|
283
|
+
async getDownload(downloadId, actor) {
|
|
284
|
+
const download = await this.opensDownload(downloadId, actor);
|
|
285
|
+
if (!download) throw new NotFoundError("Download", downloadId);
|
|
226
286
|
return {
|
|
227
287
|
download,
|
|
228
|
-
assets: await this.content.listDownloadAssets(
|
|
288
|
+
assets: await this.content.listDownloadAssets(downloadId, this.system(actor))
|
|
229
289
|
};
|
|
230
290
|
}
|
|
231
|
-
async thumbnailFile(
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
291
|
+
async thumbnailFile(owner, id, actor) {
|
|
292
|
+
const system = this.system(actor);
|
|
293
|
+
const item = owner === "event" ? (await this.seeEvents([id], actor))[0]?.event : owner === "course" ? await this.content.findCourse(id, system) : owner === "download" ? await this.content.findDownload(id, system) : await this.content.findCommunity(id, system);
|
|
294
|
+
if (!item?.thumbnailAssetId || owner !== "event" && item.status !== "published" && !actor.permissions.has(READ_OF[owner], id)) throw new NotFoundError(THUMBNAIL_OF[owner], id);
|
|
295
|
+
return signed(await this.files.signFile(actor.orgId, item.thumbnailAssetId), THUMBNAIL_OF[owner], id);
|
|
235
296
|
}
|
|
236
|
-
async activityFile(
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
if (!
|
|
240
|
-
|
|
297
|
+
async activityFile(activityId, assetId, actor) {
|
|
298
|
+
const system = this.system(actor);
|
|
299
|
+
const activity = await this.content.getActivity(activityId, system);
|
|
300
|
+
if (!activity) throw new NotFoundError("Lesson file", assetId);
|
|
301
|
+
if (!actor.permissions.has("courses:read", activity.courseId)) {
|
|
302
|
+
if (!isActivityPublished(activity.settings) || !await this.opensCourse(activity.courseId, actor)) throw new NotFoundError("Lesson file", assetId);
|
|
241
303
|
}
|
|
242
|
-
if (!(await this.content.listCourseActivityAssets(
|
|
243
|
-
return this.files.signFile(orgId, assetId);
|
|
244
|
-
}
|
|
245
|
-
async downloadFile(
|
|
246
|
-
if (!
|
|
247
|
-
const file = (await this.content.listDownloadAssets(
|
|
248
|
-
if (!file)
|
|
249
|
-
return this.files.signFile(orgId, assetId, { saveAs: file.displayName ?? file.filename });
|
|
250
|
-
}
|
|
251
|
-
async
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
304
|
+
if (!(await this.content.listCourseActivityAssets(activity.courseId, system)).some((link) => link.activityId === activityId && link.assetId === assetId)) throw new NotFoundError("Lesson file", assetId);
|
|
305
|
+
return signed(await this.files.signFile(actor.orgId, assetId), "Lesson file", assetId);
|
|
306
|
+
}
|
|
307
|
+
async downloadFile(downloadId, assetId, actor) {
|
|
308
|
+
if (!await this.opensDownload(downloadId, actor)) throw new NotFoundError("Download file", assetId);
|
|
309
|
+
const file = (await this.content.listDownloadAssets(downloadId, this.system(actor))).find((f) => f.assetId === assetId);
|
|
310
|
+
if (!file) throw new NotFoundError("Download file", assetId);
|
|
311
|
+
return signed(await this.files.signFile(actor.orgId, assetId, { saveAs: file.displayName ?? file.filename }), "Download file", assetId);
|
|
312
|
+
}
|
|
313
|
+
async seeEvents(ids, actor) {
|
|
314
|
+
if (ids.length === 0) return [];
|
|
315
|
+
const system = this.system(actor);
|
|
316
|
+
const [events, attended] = await Promise.all([this.content.findEvents(ids, system), ids.length === 1 ? this.access.hasAccess(actor.orgId, actor.id, ids[0]).then((attending) => attending ? [ids[0]] : []) : this.access.listAccessibleContent(actor.orgId, actor.id, "event")]);
|
|
317
|
+
const attending = new Set(attended);
|
|
318
|
+
const byId = new Map(events.map((event) => [event.id, event]));
|
|
319
|
+
return ids.flatMap((id) => {
|
|
320
|
+
const event = byId.get(id);
|
|
321
|
+
if (!event) return [];
|
|
322
|
+
const sight = eventSight(event, {
|
|
323
|
+
canRead: actor.permissions.has("events:read", id),
|
|
324
|
+
attending: attending.has(id)
|
|
325
|
+
});
|
|
326
|
+
return sight ? [{
|
|
327
|
+
event,
|
|
328
|
+
sight,
|
|
329
|
+
attending: attending.has(id)
|
|
330
|
+
}] : [];
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
async requireEvent(eventId, actor) {
|
|
334
|
+
const [seen] = await this.seeEvents([eventId], actor);
|
|
335
|
+
if (!seen) throw new NotFoundError("Event", eventId);
|
|
336
|
+
return seen;
|
|
337
|
+
}
|
|
338
|
+
async eventSummaries(seen, actor, now) {
|
|
339
|
+
const ids = seen.map((item) => item.event.id);
|
|
340
|
+
const attended = seen.filter((item) => item.attending).map((item) => item.event.id);
|
|
341
|
+
const [faces, direct] = await Promise.all([this.repo.eventFaces(actor.orgId, ids, EVENT_FACES), attended.length > 0 ? this.repo.directEventGrants(actor.orgId, actor.id, attended) : Promise.resolve([])]);
|
|
342
|
+
const leaves = new Set(direct);
|
|
343
|
+
return seen.map((item) => this.eventSummary(item, faces[item.event.id] ?? {
|
|
344
|
+
total: 0,
|
|
345
|
+
rows: []
|
|
346
|
+
}, leaves.has(item.event.id), actor, now));
|
|
347
|
+
}
|
|
348
|
+
eventSummary(seen, faces, canLeave, actor, now) {
|
|
349
|
+
const { event, sight, attending } = seen;
|
|
350
|
+
const id = event.id;
|
|
351
|
+
const canOpen = sight !== "public";
|
|
352
|
+
const capacity = event.settings.capacity;
|
|
353
|
+
const attendeeCount = faces.total;
|
|
354
|
+
const ended = event.endsAt.getTime() <= now.getTime();
|
|
355
|
+
const recording = sight === "read" || sight === "attendee" && ended && event.settings.replay ? event.recording : null;
|
|
356
|
+
const writes = actor.permissions.has("events:write", id);
|
|
357
|
+
const canManageAttendees = actor.permissions.has("access:write") || writes;
|
|
358
|
+
return {
|
|
359
|
+
orgId: event.orgId,
|
|
360
|
+
id,
|
|
361
|
+
type: event.type,
|
|
362
|
+
title: event.title,
|
|
363
|
+
thumbnailAssetId: event.thumbnailAssetId,
|
|
364
|
+
thumbnailUrl: event.thumbnailUrl,
|
|
365
|
+
status: event.status,
|
|
366
|
+
startsAt: event.startsAt,
|
|
367
|
+
endsAt: event.endsAt,
|
|
368
|
+
timeZone: event.timeZone,
|
|
369
|
+
location: canOpen ? event.location : null,
|
|
370
|
+
recording,
|
|
371
|
+
settings: {
|
|
372
|
+
type: event.settings.type,
|
|
373
|
+
capacity,
|
|
374
|
+
replay: event.settings.replay
|
|
375
|
+
},
|
|
376
|
+
attendeeCount,
|
|
377
|
+
attendees: faces.rows.map((row) => attendeeFace(actor.orgId, row, this.fileUrls)),
|
|
378
|
+
placesLeft: capacity === null ? null : Math.max(capacity - attendeeCount, 0),
|
|
379
|
+
viewer: {
|
|
380
|
+
attending,
|
|
381
|
+
canRegister: event.status === "published" && !attending && event.settings.type === "public" && event.startsAt.getTime() > now.getTime() && (capacity === null || attendeeCount < capacity),
|
|
382
|
+
canOpen,
|
|
383
|
+
canLeave,
|
|
384
|
+
canManageAttendees,
|
|
385
|
+
canAddAttendees: canManageAttendees && event.status === "published" && !ended,
|
|
386
|
+
canEdit: writes,
|
|
387
|
+
canCancel: writes,
|
|
388
|
+
canDelete: actor.permissions.has("events:delete", id)
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
async getEvent(eventId, actor) {
|
|
393
|
+
const seen = await this.requireEvent(eventId, actor);
|
|
394
|
+
const now = this.now();
|
|
395
|
+
const [[summary], files] = await Promise.all([this.eventSummaries([seen], actor, now), seen.sight === "public" ? Promise.resolve({}) : this.content.eventFilesFor([eventId], this.system(actor))]);
|
|
396
|
+
return {
|
|
397
|
+
...summary,
|
|
398
|
+
description: seen.event.description,
|
|
399
|
+
files: files[eventId] ?? []
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
async listEvents(query, actor) {
|
|
403
|
+
const now = this.now();
|
|
404
|
+
const reads = actor.permissions.where("events:read");
|
|
405
|
+
const page = await this.repo.events(actor.orgId, query, {
|
|
406
|
+
orgUserId: actor.id,
|
|
407
|
+
readAll: reads.org,
|
|
408
|
+
readIds: reads.content
|
|
409
|
+
}, now);
|
|
410
|
+
const rows = await this.eventSummaries(await this.seeEvents(page.rows, actor), actor, now);
|
|
260
411
|
return {
|
|
261
412
|
...page,
|
|
262
|
-
rows
|
|
263
|
-
...row,
|
|
264
|
-
imageUrl: row.imageAssetId ? this.fileUrls.personImage(row.orgUserId) : null
|
|
265
|
-
}))
|
|
413
|
+
rows
|
|
266
414
|
};
|
|
267
415
|
}
|
|
268
|
-
async
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
416
|
+
async eventCalendar(eventId, actor) {
|
|
417
|
+
const { event, sight } = await this.requireEvent(eventId, actor);
|
|
418
|
+
return eventCalendar(event, {
|
|
419
|
+
pageUrl: `${this.studentPortalUrl}/events/${encodeURIComponent(event.id)}`,
|
|
420
|
+
withLocation: sight !== "public",
|
|
421
|
+
now: this.now()
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
async eventAttendees(eventId, query, actor) {
|
|
425
|
+
actor.permissions.require("events:read", eventId);
|
|
426
|
+
if (!await this.content.findEvent(eventId, this.system(actor))) throw new NotFoundError("Event", eventId);
|
|
427
|
+
const page = await this.repo.eventAttendees(actor.orgId, eventId, query);
|
|
428
|
+
return {
|
|
429
|
+
...page,
|
|
430
|
+
rows: page.rows.map((row) => attendeeView(actor.orgId, row, this.fileUrls))
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
async eventFile(eventId, assetId, actor) {
|
|
434
|
+
const [seen] = await this.seeEvents([eventId], actor);
|
|
435
|
+
if (!seen || seen.sight === "public") throw new NotFoundError("Event file", assetId);
|
|
436
|
+
const file = (await this.content.eventFilesFor([eventId], this.system(actor)))[eventId]?.find((f) => f.assetId === assetId);
|
|
437
|
+
if (!file) throw new NotFoundError("Event file", assetId);
|
|
438
|
+
return signed(await this.files.signFile(actor.orgId, assetId, { saveAs: file.displayName ?? file.filename }), "Event file", assetId);
|
|
439
|
+
}
|
|
440
|
+
async directory(communityId, query, actor) {
|
|
441
|
+
if (!await this.access.isCommunityMember(communityId, actor)) throw new NotFoundError("Community", communityId);
|
|
442
|
+
const orgId = actor.orgId;
|
|
443
|
+
if (!await this.content.findCommunity(communityId, this.system(actor))) throw new NotFoundError("Community", communityId);
|
|
444
|
+
const readers = await this.people.holders(orgId, "communities:read", communityId);
|
|
445
|
+
const page = await this.repo.directory(orgId, communityId, query, readers);
|
|
446
|
+
const permissions = await this.people.permissionsOfMany(orgId, page.rows.map((row) => row.orgUserId));
|
|
447
|
+
return {
|
|
448
|
+
...page,
|
|
449
|
+
rows: page.rows.map((row) => {
|
|
450
|
+
const held = permissions.get(row.orgUserId);
|
|
451
|
+
const item = held?.roleOn(communityId);
|
|
452
|
+
const org = held?.roleOn();
|
|
453
|
+
return {
|
|
454
|
+
...row,
|
|
455
|
+
imageUrl: row.imageAssetId ? this.fileUrls.publicImage(orgId, row.orgUserId, row.imageAssetId) : null,
|
|
456
|
+
team: (item?.team ?? false) || (org?.team ?? false),
|
|
457
|
+
roleName: item?.team ? item.name : org?.team ? org.name : null,
|
|
458
|
+
opensEverySpace: (held?.has("communities:read", communityId) || held?.has("communities:moderate", communityId)) ?? false
|
|
459
|
+
};
|
|
460
|
+
})
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
async communityHome(communityId, actor) {
|
|
464
|
+
if (!await this.access.isCommunityMember(communityId, actor)) throw new NotFoundError("Community", communityId);
|
|
465
|
+
const system = this.system(actor);
|
|
466
|
+
const community = await this.content.findCommunity(communityId, system);
|
|
467
|
+
if (!community) throw new NotFoundError("Community", communityId);
|
|
468
|
+
const [spaces, everySpace] = await Promise.all([this.content.listSpaces(communityId, system), this.access.opensEverySpace(actor, communityId)]);
|
|
469
|
+
const itemRole = actor.permissions.roleOn(communityId);
|
|
470
|
+
const orgRole = actor.permissions.roleOn();
|
|
471
|
+
const role = itemRole.team || !orgRole.team ? itemRole : orgRole;
|
|
273
472
|
return {
|
|
274
473
|
communityId,
|
|
275
474
|
title: community.title,
|
|
276
475
|
description: community.description,
|
|
277
476
|
thumbnailUrl: community.thumbnailUrl,
|
|
278
477
|
dm: community.settings.dm,
|
|
279
|
-
spaces: await this.homeSpaces(
|
|
478
|
+
spaces: await this.homeSpaces(actor, communityId, spaces, everySpace),
|
|
479
|
+
viewer: {
|
|
480
|
+
permissions: PERMISSION_KEYS.filter((p) => actor.permissions.has(p, communityId)),
|
|
481
|
+
opensEverySpace: everySpace,
|
|
482
|
+
team: itemRole.team || orgRole.team,
|
|
483
|
+
roleName: role.name,
|
|
484
|
+
canCreateEvents: actor.permissions.has("events:write")
|
|
485
|
+
}
|
|
280
486
|
};
|
|
281
487
|
}
|
|
282
|
-
async communitySpace(
|
|
283
|
-
if (!await this.access.isCommunityMember(
|
|
284
|
-
const space = await this.content.getSpace(
|
|
285
|
-
if (!space || space.communityId !== communityId)
|
|
286
|
-
const
|
|
287
|
-
|
|
488
|
+
async communitySpace(communityId, spaceId, actor) {
|
|
489
|
+
if (!await this.access.isCommunityMember(communityId, actor)) throw new NotFoundError("Space", spaceId);
|
|
490
|
+
const space = await this.content.getSpace(spaceId, this.system(actor));
|
|
491
|
+
if (!space || space.communityId !== communityId) throw new NotFoundError("Space", spaceId);
|
|
492
|
+
const everySpace = await this.access.opensEverySpace(actor, communityId);
|
|
493
|
+
const [view] = await this.homeSpaces(actor, communityId, [space], everySpace);
|
|
494
|
+
if (!view) throw new NotFoundError("Space", spaceId);
|
|
495
|
+
return view;
|
|
288
496
|
}
|
|
289
|
-
async homeSpaces(
|
|
497
|
+
async homeSpaces(actor, communityId, spaces, everySpace) {
|
|
498
|
+
const orgId = actor.orgId;
|
|
499
|
+
const excluding = await this.access.everySpaceOpeners(orgId, communityId);
|
|
290
500
|
const [openIds, counts, standings, subscribed] = await Promise.all([
|
|
291
|
-
this.access.openSpaceIds(
|
|
292
|
-
this.repo.spaceMemberCounts(orgId, communityId),
|
|
293
|
-
this.access.spaceStandings(
|
|
501
|
+
this.access.openSpaceIds(communityId, actor),
|
|
502
|
+
this.repo.spaceMemberCounts(orgId, communityId, excluding),
|
|
503
|
+
this.access.spaceStandings(communityId, actor),
|
|
294
504
|
this.subscriptions.viewerSubscriptions(orgId, actor.id, "space", spaces.map((space) => space.id), /* @__PURE__ */ new Date())
|
|
295
505
|
]);
|
|
296
506
|
const open = new Set(openIds);
|
|
297
|
-
const seen = spaces.filter((space) => seesSpace(
|
|
507
|
+
const seen = spaces.filter((space) => seesSpace(everySpace, space.accessRule, standings[space.id]));
|
|
298
508
|
return Promise.all(seen.map(async (space) => {
|
|
299
509
|
const memberCount = counts[space.id] ?? 0;
|
|
300
510
|
const base = {
|
|
@@ -318,30 +528,31 @@ var MemberReportServiceImpl = class {
|
|
|
318
528
|
id: topic.id,
|
|
319
529
|
name: topic.name
|
|
320
530
|
})),
|
|
321
|
-
links: await this.linkViews(
|
|
531
|
+
links: await this.linkViews(actor, space.links),
|
|
322
532
|
subscription: subscribed[space.id] ?? null
|
|
323
533
|
};
|
|
324
534
|
}));
|
|
325
535
|
}
|
|
326
|
-
async linkViews(
|
|
327
|
-
const
|
|
536
|
+
async linkViews(actor, links) {
|
|
537
|
+
const system = this.system(actor);
|
|
538
|
+
const shown = (type, id, status) => status === "published" || actor.permissions.has(READ_OF[type], id);
|
|
328
539
|
return (await Promise.all(links.map(async (link) => {
|
|
329
|
-
const course = await this.content.
|
|
330
|
-
if (course) return shown(course.status) ? {
|
|
540
|
+
const course = await this.content.findCourse(link.contentId, system);
|
|
541
|
+
if (course) return shown("course", link.contentId, course.status) ? {
|
|
331
542
|
id: link.id,
|
|
332
543
|
contentId: link.contentId,
|
|
333
544
|
type: "course",
|
|
334
545
|
title: course.title
|
|
335
546
|
} : null;
|
|
336
|
-
const download = await this.content.
|
|
337
|
-
if (download) return shown(download.status) ? {
|
|
547
|
+
const download = await this.content.findDownload(link.contentId, system);
|
|
548
|
+
if (download) return shown("download", link.contentId, download.status) ? {
|
|
338
549
|
id: link.id,
|
|
339
550
|
contentId: link.contentId,
|
|
340
551
|
type: "download",
|
|
341
552
|
title: download.title
|
|
342
553
|
} : null;
|
|
343
|
-
const community = await this.content.
|
|
344
|
-
if (community) return shown(community.status) ? {
|
|
554
|
+
const community = await this.content.findCommunity(link.contentId, system);
|
|
555
|
+
if (community) return shown("community", link.contentId, community.status) ? {
|
|
345
556
|
id: link.id,
|
|
346
557
|
contentId: link.contentId,
|
|
347
558
|
type: "community",
|
|
@@ -351,6 +562,10 @@ var MemberReportServiceImpl = class {
|
|
|
351
562
|
}))).filter((view) => view !== null);
|
|
352
563
|
}
|
|
353
564
|
};
|
|
565
|
+
function signed(url, what, id) {
|
|
566
|
+
if (!url) throw new NotFoundError(what, id);
|
|
567
|
+
return url;
|
|
568
|
+
}
|
|
354
569
|
function standingOf(space, open, memberCount, status) {
|
|
355
570
|
if (space.accessRule === "all_members" || open && status !== "active") return "open";
|
|
356
571
|
if (status === "active") return "member";
|