@headless-lms/core 0.1.0 → 0.3.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 +90 -9
- package/dist/assets/events.js +19 -3
- package/dist/assets/events.js.map +1 -1
- package/dist/assets/file-urls.d.ts +20 -0
- package/dist/assets/file-urls.js +25 -0
- package/dist/assets/file-urls.js.map +1 -0
- package/dist/assets/index.d.ts +5 -4
- package/dist/assets/index.js +3 -2
- package/dist/assets/model.d.ts +2 -2
- package/dist/assets/ports.d.ts +45 -15
- package/dist/assets/service.d.ts +39 -7
- package/dist/assets/service.js +292 -37
- package/dist/assets/service.js.map +1 -1
- package/dist/automations/actions.d.ts +12 -15
- package/dist/automations/actions.js +188 -30
- package/dist/automations/actions.js.map +1 -1
- package/dist/automations/catalog.d.ts +5 -1
- package/dist/automations/catalog.js +514 -197
- package/dist/automations/catalog.js.map +1 -1
- package/dist/automations/community-derivations.d.ts +14 -0
- package/dist/automations/community-derivations.js +439 -0
- package/dist/automations/community-derivations.js.map +1 -0
- package/dist/automations/community-mail.d.ts +112 -0
- package/dist/automations/community-mail.js +90 -0
- package/dist/automations/community-mail.js.map +1 -0
- package/dist/automations/community-notifications.d.ts +16 -0
- package/dist/automations/community-notifications.js +84 -0
- package/dist/automations/community-notifications.js.map +1 -0
- package/dist/automations/events.d.ts +74 -24
- package/dist/automations/events.js +5 -5
- package/dist/automations/events.js.map +1 -1
- package/dist/automations/index.d.ts +7 -5
- package/dist/automations/index.js +3 -2
- package/dist/automations/model.d.ts +20 -3
- package/dist/automations/model.js +36 -3
- package/dist/automations/model.js.map +1 -1
- package/dist/automations/ports.d.ts +27 -8
- package/dist/automations/schedule.d.ts +6 -0
- package/dist/automations/schedule.js +41 -0
- package/dist/automations/schedule.js.map +1 -0
- package/dist/automations/seeds.d.ts +17 -0
- package/dist/automations/seeds.js +235 -0
- package/dist/automations/seeds.js.map +1 -0
- package/dist/automations/service.d.ts +41 -6
- package/dist/automations/service.js +542 -59
- package/dist/automations/service.js.map +1 -1
- package/dist/automations/types.d.ts +2 -2
- package/dist/automations/webhook-signing.d.ts +7 -0
- package/dist/automations/webhook-signing.js +22 -0
- package/dist/automations/webhook-signing.js.map +1 -0
- package/dist/content/events.d.ts +1013 -25
- package/dist/content/events.js +168 -19
- package/dist/content/events.js.map +1 -1
- package/dist/content/index.d.ts +5 -5
- package/dist/content/index.js +2 -2
- package/dist/content/model.d.ts +2 -2
- package/dist/content/ports.d.ts +109 -25
- package/dist/content/service.d.ts +68 -23
- package/dist/content/service.js +647 -60
- package/dist/content/service.js.map +1 -1
- package/dist/content/types.d.ts +2 -2
- package/dist/discussion/authors.d.ts +10 -0
- package/dist/discussion/authors.js +23 -0
- package/dist/discussion/authors.js.map +1 -0
- package/dist/discussion/chats.d.ts +104 -0
- package/dist/discussion/chats.js +798 -0
- package/dist/discussion/chats.js.map +1 -0
- package/dist/discussion/events.d.ts +633 -14
- package/dist/discussion/events.js +134 -5
- package/dist/discussion/events.js.map +1 -1
- package/dist/discussion/index.d.ts +7 -3
- package/dist/discussion/index.js +4 -1
- package/dist/discussion/model.d.ts +1 -2
- package/dist/discussion/ports.d.ts +288 -27
- package/dist/discussion/ports.js +6 -1
- package/dist/discussion/ports.js.map +1 -0
- package/dist/discussion/posts.d.ts +103 -0
- package/dist/discussion/posts.js +723 -0
- package/dist/discussion/posts.js.map +1 -0
- package/dist/discussion/service.d.ts +33 -11
- package/dist/discussion/service.js +297 -81
- package/dist/discussion/service.js.map +1 -1
- package/dist/entitlements/events.d.ts +264 -13
- package/dist/entitlements/events.js +49 -5
- package/dist/entitlements/events.js.map +1 -1
- package/dist/entitlements/index.d.ts +5 -4
- package/dist/entitlements/index.js +2 -1
- package/dist/entitlements/model.d.ts +3 -2
- package/dist/entitlements/ports.d.ts +124 -11
- package/dist/entitlements/rules.d.ts +12 -0
- package/dist/entitlements/rules.js +17 -0
- package/dist/entitlements/rules.js.map +1 -0
- package/dist/entitlements/service.d.ts +54 -3
- package/dist/entitlements/service.js +473 -2
- package/dist/entitlements/service.js.map +1 -1
- package/dist/identity/access.d.ts +6 -0
- package/dist/identity/access.js +7 -0
- package/dist/identity/access.js.map +1 -0
- package/dist/identity/events.d.ts +17 -3
- package/dist/identity/events.js +12 -2
- package/dist/identity/events.js.map +1 -1
- package/dist/identity/index.d.ts +6 -4
- package/dist/identity/index.js +3 -1
- package/dist/identity/model.d.ts +2 -1
- package/dist/identity/notifications.d.ts +27 -0
- package/dist/identity/notifications.js +101 -0
- package/dist/identity/notifications.js.map +1 -0
- package/dist/identity/ports.d.ts +76 -3
- package/dist/identity/service.d.ts +17 -3
- package/dist/identity/service.js +73 -5
- package/dist/identity/service.js.map +1 -1
- package/dist/integrations/events.d.ts +27 -3
- package/dist/integrations/events.js +15 -3
- package/dist/integrations/events.js.map +1 -1
- package/dist/integrations/model.js +1 -1
- package/dist/integrations/model.js.map +1 -1
- package/dist/integrations/service.js +2 -2
- package/dist/integrations/service.js.map +1 -1
- package/dist/organizations/access-scopes.d.ts +19 -0
- package/dist/organizations/access-scopes.js +89 -0
- package/dist/organizations/access-scopes.js.map +1 -0
- package/dist/organizations/events.d.ts +234 -25
- package/dist/organizations/events.js +58 -9
- package/dist/organizations/events.js.map +1 -1
- package/dist/organizations/index.d.ts +8 -7
- package/dist/organizations/index.js +4 -3
- package/dist/organizations/members.d.ts +8 -5
- package/dist/organizations/members.js.map +1 -1
- package/dist/organizations/ports.d.ts +20 -21
- package/dist/organizations/roles.d.ts +6 -10
- package/dist/organizations/roles.js +19 -7
- package/dist/organizations/roles.js.map +1 -1
- package/dist/organizations/service.d.ts +28 -14
- package/dist/organizations/service.js +274 -105
- package/dist/organizations/service.js.map +1 -1
- package/dist/organizations/types.d.ts +2 -11
- package/dist/progress/events.d.ts +34 -2
- package/dist/progress/events.js +15 -2
- package/dist/progress/events.js.map +1 -1
- package/dist/progress/index.d.ts +2 -2
- package/dist/progress/ports.d.ts +6 -1
- package/dist/progress/service.d.ts +5 -3
- package/dist/progress/service.js +9 -3
- package/dist/progress/service.js.map +1 -1
- package/dist/reporting/admin/index.d.ts +4 -0
- package/dist/reporting/admin/index.js +2 -0
- package/dist/reporting/admin/model.d.ts +108 -0
- package/dist/reporting/admin/ports.d.ts +27 -0
- package/dist/reporting/admin/service.d.ts +22 -0
- package/dist/reporting/admin/service.js +38 -0
- package/dist/reporting/admin/service.js.map +1 -0
- package/dist/reporting/member/index.d.ts +5 -0
- package/dist/reporting/member/index.js +2 -0
- package/dist/reporting/member/model.d.ts +124 -0
- package/dist/reporting/member/ports.d.ts +45 -0
- package/dist/reporting/member/service.d.ts +73 -0
- package/dist/reporting/member/service.js +286 -0
- package/dist/reporting/member/service.js.map +1 -0
- package/dist/shared/actor.d.ts +9 -0
- package/dist/shared/errors.d.ts +7 -1
- package/dist/shared/errors.js +10 -1
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/events.d.ts +5 -3
- package/dist/shared/events.js +1 -0
- package/dist/shared/events.js.map +1 -1
- package/dist/shared/id.d.ts +12 -0
- package/dist/shared/id.js +13 -1
- package/dist/shared/id.js.map +1 -1
- package/dist/shared/mailer.d.ts +6 -1
- package/dist/shared/mailer.js.map +1 -1
- package/dist/shared/network.d.ts +10 -0
- package/dist/shared/network.js +211 -0
- package/dist/shared/network.js.map +1 -0
- package/dist/shared/settings.js.map +1 -1
- package/dist/types/assets.d.ts +2 -2
- package/dist/types/automations.d.ts +21 -2
- package/dist/types/content.d.ts +2 -2
- package/dist/types/discussion.d.ts +12 -3
- package/dist/types/email-templates.d.ts +124 -1
- package/dist/types/entitlements.d.ts +2 -2
- package/dist/types/events.d.ts +3 -3
- package/dist/types/identity.d.ts +48 -2
- package/dist/types/index.d.ts +10 -10
- package/dist/types/organizations.d.ts +2 -2
- package/dist/types/ports.d.ts +7 -1
- package/dist/types/schemas/assets.d.ts +67 -36
- package/dist/types/schemas/assets.js +19 -13
- package/dist/types/schemas/assets.js.map +1 -1
- package/dist/types/schemas/automations.d.ts +88 -4
- package/dist/types/schemas/automations.js +46 -6
- package/dist/types/schemas/automations.js.map +1 -1
- package/dist/types/schemas/content.d.ts +385 -20
- package/dist/types/schemas/content.js +178 -15
- package/dist/types/schemas/content.js.map +1 -1
- package/dist/types/schemas/credentials.js.map +1 -1
- package/dist/types/schemas/discussion.d.ts +379 -4
- package/dist/types/schemas/discussion.js +209 -7
- package/dist/types/schemas/discussion.js.map +1 -1
- package/dist/types/schemas/entitlements.d.ts +44 -4
- package/dist/types/schemas/entitlements.js +32 -4
- package/dist/types/schemas/entitlements.js.map +1 -1
- package/dist/types/schemas/identity.d.ts +115 -5
- package/dist/types/schemas/identity.js +59 -6
- package/dist/types/schemas/identity.js.map +1 -1
- package/dist/types/schemas/index.d.ts +9 -9
- package/dist/types/schemas/index.js +9 -9
- package/dist/types/schemas/integrations.js.map +1 -1
- package/dist/types/schemas/organizations.d.ts +27 -5
- package/dist/types/schemas/organizations.js +14 -7
- package/dist/types/schemas/organizations.js.map +1 -1
- package/dist/types/schemas/outbox.d.ts +1 -0
- package/dist/types/schemas/outbox.js +1 -0
- package/dist/types/schemas/outbox.js.map +1 -1
- package/dist/types/schemas/progress.d.ts +1 -0
- package/dist/types/schemas/progress.js +1 -0
- package/dist/types/schemas/progress.js.map +1 -1
- package/dist/types/schemas/settings.js.map +1 -1
- package/dist/types/schemas/shared.d.ts +4 -1
- package/dist/types/schemas/shared.js +7 -1
- package/dist/types/schemas/shared.js.map +1 -1
- package/dist/types/shared.d.ts +1 -1
- package/package.json +2 -2
- package/dist/reporting/dashboard/index.d.ts +0 -4
- package/dist/reporting/dashboard/index.js +0 -2
- package/dist/reporting/dashboard/model.d.ts +0 -14
- package/dist/reporting/dashboard/ports.d.ts +0 -13
- package/dist/reporting/dashboard/service.d.ts +0 -19
- package/dist/reporting/dashboard/service.js +0 -20
- package/dist/reporting/dashboard/service.js.map +0 -1
- package/dist/reporting/learn/index.d.ts +0 -5
- package/dist/reporting/learn/index.js +0 -2
- package/dist/reporting/learn/model.d.ts +0 -23
- package/dist/reporting/learn/ports.d.ts +0 -42
- package/dist/reporting/learn/service.d.ts +0 -48
- package/dist/reporting/learn/service.js +0 -111
- package/dist/reporting/learn/service.js.map +0 -1
- package/dist/reporting/students/index.d.ts +0 -4
- package/dist/reporting/students/index.js +0 -2
- package/dist/reporting/students/model.d.ts +0 -31
- package/dist/reporting/students/ports.d.ts +0 -13
- package/dist/reporting/students/ports.js +0 -1
- package/dist/reporting/students/service.d.ts +0 -19
- package/dist/reporting/students/service.js +0 -20
- package/dist/reporting/students/service.js.map +0 -1
- /package/dist/reporting/{dashboard → admin}/model.js +0 -0
- /package/dist/reporting/{dashboard → admin}/ports.js +0 -0
- /package/dist/reporting/{learn → member}/model.js +0 -0
- /package/dist/reporting/{learn → member}/ports.js +0 -0
- /package/dist/{reporting/students/model.js → shared/actor.js} +0 -0
package/dist/identity/events.js
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import { userSchema } from "../types/schemas/identity.js";
|
|
2
2
|
import { defineEvent } from "../shared/events.js";
|
|
3
3
|
//#region src/identity/events.ts
|
|
4
|
+
const publicUser = userSchema.pick({
|
|
5
|
+
id: true,
|
|
6
|
+
email: true,
|
|
7
|
+
firstName: true,
|
|
8
|
+
lastName: true,
|
|
9
|
+
createdAt: true,
|
|
10
|
+
updatedAt: true
|
|
11
|
+
}).strip();
|
|
4
12
|
const identityEvents = {
|
|
5
13
|
userCreated: defineEvent({
|
|
6
14
|
type: "identity.user.created",
|
|
7
15
|
version: 1,
|
|
8
|
-
data: userSchema
|
|
16
|
+
data: userSchema,
|
|
17
|
+
publicData: publicUser
|
|
9
18
|
}),
|
|
10
19
|
userUpdated: defineEvent({
|
|
11
20
|
type: "identity.user.updated",
|
|
12
21
|
version: 1,
|
|
13
|
-
data: userSchema
|
|
22
|
+
data: userSchema,
|
|
23
|
+
publicData: publicUser
|
|
14
24
|
}),
|
|
15
25
|
userDeleted: defineEvent({
|
|
16
26
|
type: "identity.user.deleted",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","names":[],"sources":["../../src/identity/events.ts"],"sourcesContent":["import { userSchema } from '../types/schemas/index.js';\nimport { defineEvent, type EventOf, type EventOfValues } from '../shared/ports.js';\n\nexport const identityEvents = {\n userCreated: defineEvent({\n type: 'identity.user.created',\n version: 1,\n data: userSchema,\n }),\n userUpdated: defineEvent({\n type: 'identity.user.updated',\n version: 1,\n data: userSchema,\n }),\n userDeleted: defineEvent({\n type: 'identity.user.deleted',\n version: 1,\n data: userSchema,\n }),\n};\n\nexport type UserCreated = EventOf<typeof identityEvents.userCreated>;\nexport type UserUpdated = EventOf<typeof identityEvents.userUpdated>;\nexport type UserDeleted = EventOf<typeof identityEvents.userDeleted>;\nexport type IdentityEvent = EventOfValues<typeof identityEvents>;\n"],"mappings":";;;AAGA,MAAa,iBAAiB;CAC5B,aAAa,YAAY;EACvB,MAAM;EACN,SAAS;EACT,MAAM;
|
|
1
|
+
{"version":3,"file":"events.js","names":[],"sources":["../../src/identity/events.ts"],"sourcesContent":["import { userSchema } from '../types/schemas/index.js';\nimport { defineEvent, type EventOf, type EventOfValues } from '../shared/ports.js';\n\nconst publicUser = userSchema\n .pick({\n id: true,\n email: true,\n firstName: true,\n lastName: true,\n createdAt: true,\n updatedAt: true,\n })\n .strip();\n\nexport const identityEvents = {\n userCreated: defineEvent({\n type: 'identity.user.created',\n version: 1,\n data: userSchema,\n publicData: publicUser,\n }),\n userUpdated: defineEvent({\n type: 'identity.user.updated',\n version: 1,\n data: userSchema,\n publicData: publicUser,\n }),\n userDeleted: defineEvent({\n type: 'identity.user.deleted',\n version: 1,\n data: userSchema,\n }),\n};\n\nexport type UserCreated = EventOf<typeof identityEvents.userCreated>;\nexport type UserUpdated = EventOf<typeof identityEvents.userUpdated>;\nexport type UserDeleted = EventOf<typeof identityEvents.userDeleted>;\nexport type IdentityEvent = EventOfValues<typeof identityEvents>;\n"],"mappings":";;;AAGA,MAAM,aAAa,WAChB,KAAK;CACJ,IAAI;CACJ,OAAO;CACP,WAAW;CACX,UAAU;CACV,WAAW;CACX,WAAW;AACb,CAAC,CAAC,CACD,MAAM;AAET,MAAa,iBAAiB;CAC5B,aAAa,YAAY;EACvB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,aAAa,YAAY;EACvB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,aAAa,YAAY;EACvB,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;AACH"}
|
package/dist/identity/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { CreateUserInput, ProvisionUserInput, UpdateUserInput } from "../types/schemas/identity.js";
|
|
1
|
+
import { CreateUserInput, Notification, NotificationKind, NotificationPreference, ProvisionUserInput, UpdateUserInput, UserProfile, UserProfileView } from "../types/schemas/identity.js";
|
|
2
2
|
import { User, UserId } from "../types/identity.js";
|
|
3
|
-
import { IdentityEvent, UserCreated, UserDeleted, UserUpdated, identityEvents } from "./events.js";
|
|
4
3
|
import "./model.js";
|
|
5
4
|
import "./types.js";
|
|
6
|
-
import { AuthHeaders, IdentityRepository, IdentityService, SessionAdmin, UserEditor, UserProvisioner, UserResolver } from "./ports.js";
|
|
5
|
+
import { AuthHeaders, IdentityRepository, IdentityService, NewNotification, NotificationDesk, NotificationInbox, NotificationPage, NotificationService, NotificationsQuery, NotificationsRepository, ProfilePatch, SessionAdmin, UpdateProfileInput, UserEditor, UserProvisioner, UserResolver } from "./ports.js";
|
|
7
6
|
import { IdentityServiceImpl } from "./service.js";
|
|
8
|
-
|
|
7
|
+
import { NotificationServiceImpl, defaultPreference } from "./notifications.js";
|
|
8
|
+
import { IdentityEvent, UserCreated, UserDeleted, UserUpdated, identityEvents } from "./events.js";
|
|
9
|
+
import { ACCESS_TOKEN_TTL_SECONDS, ORG_CLAIM } from "./access.js";
|
|
10
|
+
export { ACCESS_TOKEN_TTL_SECONDS, type AuthHeaders, type CreateUserInput, type IdentityEvent, type IdentityRepository, type IdentityService, IdentityServiceImpl, type NewNotification, type Notification, type NotificationDesk, type NotificationInbox, type NotificationKind, type NotificationPage, type NotificationPreference, type NotificationService, NotificationServiceImpl, type NotificationsQuery, type NotificationsRepository, ORG_CLAIM, type ProfilePatch, type ProvisionUserInput, type SessionAdmin, type UpdateProfileInput, type UpdateUserInput, type User, type UserCreated, type UserDeleted, type UserEditor, type UserId, type UserProfile, type UserProfileView, type UserProvisioner, type UserResolver, type UserUpdated, defaultPreference, identityEvents };
|
package/dist/identity/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { identityEvents } from "./events.js";
|
|
2
2
|
import { IdentityServiceImpl } from "./service.js";
|
|
3
|
-
|
|
3
|
+
import { NotificationServiceImpl, defaultPreference } from "./notifications.js";
|
|
4
|
+
import { ACCESS_TOKEN_TTL_SECONDS, ORG_CLAIM } from "./access.js";
|
|
5
|
+
export { ACCESS_TOKEN_TTL_SECONDS, IdentityServiceImpl, NotificationServiceImpl, ORG_CLAIM, defaultPreference, identityEvents };
|
package/dist/identity/model.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Notification, NotificationKind, NotificationPreference, UserProfile, UserProfileView } from "../types/schemas/identity.js";
|
|
1
2
|
import { User } from "../types/identity.js";
|
|
2
3
|
import "../types/index.js";
|
|
3
|
-
export type { User };
|
|
4
|
+
export type { Notification, NotificationKind, NotificationPreference, User, UserProfile, UserProfileView };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Logger } from "../types/ports.js";
|
|
2
|
+
import { Notification, NotificationKind, NotificationPreference } from "../types/schemas/identity.js";
|
|
3
|
+
import "../shared/ports.js";
|
|
4
|
+
import "./model.js";
|
|
5
|
+
import { NewNotification, NotificationPage, NotificationService, NotificationsQuery, NotificationsRepository } from "./ports.js";
|
|
6
|
+
//#region src/identity/notifications.d.ts
|
|
7
|
+
declare function defaultPreference(kind: NotificationKind): NotificationPreference;
|
|
8
|
+
declare class NotificationServiceImpl implements NotificationService {
|
|
9
|
+
private readonly repo;
|
|
10
|
+
private readonly logger;
|
|
11
|
+
constructor(params: {
|
|
12
|
+
repo: NotificationsRepository;
|
|
13
|
+
logger?: Logger;
|
|
14
|
+
});
|
|
15
|
+
notify(orgId: string, notifications: NewNotification[]): Promise<void>;
|
|
16
|
+
preferencesFor(orgId: string, userIds: string[], kind: NotificationKind): Promise<Record<string, NotificationPreference>>;
|
|
17
|
+
listNotifications(orgId: string, userId: string, query: NotificationsQuery): Promise<NotificationPage>;
|
|
18
|
+
markNotificationRead(orgId: string, userId: string, notificationId: string): Promise<Notification>;
|
|
19
|
+
markAllNotificationsRead(orgId: string, userId: string): Promise<{
|
|
20
|
+
updated: number;
|
|
21
|
+
}>;
|
|
22
|
+
notificationPreferences(orgId: string, userId: string): Promise<NotificationPreference[]>;
|
|
23
|
+
setNotificationPreferences(orgId: string, userId: string, preferences: NotificationPreference[]): Promise<NotificationPreference[]>;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { NotificationServiceImpl, defaultPreference };
|
|
27
|
+
//# sourceMappingURL=notifications.d.ts.map
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { notificationKindSchema } from "../types/schemas/identity.js";
|
|
2
|
+
import { genId } from "../shared/id.js";
|
|
3
|
+
import { NotFoundError } from "../shared/errors.js";
|
|
4
|
+
import { noopLogger } from "../shared/logger.js";
|
|
5
|
+
//#region src/identity/notifications.ts
|
|
6
|
+
function defaultPreference(kind) {
|
|
7
|
+
return {
|
|
8
|
+
kind,
|
|
9
|
+
inApp: true,
|
|
10
|
+
email: true
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
var NotificationServiceImpl = class {
|
|
14
|
+
repo;
|
|
15
|
+
logger;
|
|
16
|
+
constructor(params) {
|
|
17
|
+
this.repo = params.repo;
|
|
18
|
+
this.logger = params.logger ?? noopLogger;
|
|
19
|
+
}
|
|
20
|
+
async notify(orgId, notifications) {
|
|
21
|
+
if (notifications.length === 0) return;
|
|
22
|
+
const now = /* @__PURE__ */ new Date();
|
|
23
|
+
const rows = notifications.map((notification) => ({
|
|
24
|
+
...notification,
|
|
25
|
+
orgId,
|
|
26
|
+
id: genId("notification"),
|
|
27
|
+
createdAt: now,
|
|
28
|
+
readAt: null
|
|
29
|
+
}));
|
|
30
|
+
await this.repo.insert(orgId, rows);
|
|
31
|
+
this.logger.info("notifications added", {
|
|
32
|
+
orgId,
|
|
33
|
+
kinds: [...new Set(rows.map((row) => row.kind))],
|
|
34
|
+
count: rows.length
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async preferencesFor(orgId, userIds, kind) {
|
|
38
|
+
const unique = [...new Set(userIds)];
|
|
39
|
+
const stored = await this.repo.preferences(orgId, unique);
|
|
40
|
+
const result = {};
|
|
41
|
+
for (const userId of unique) result[userId] = defaultPreference(kind);
|
|
42
|
+
for (const row of stored) if (row.kind === kind) result[row.userId] = {
|
|
43
|
+
kind,
|
|
44
|
+
inApp: row.inApp,
|
|
45
|
+
email: row.email
|
|
46
|
+
};
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
async listNotifications(orgId, userId, query) {
|
|
50
|
+
const page = await this.repo.page(orgId, userId, query);
|
|
51
|
+
this.logger.debug("notifications listed", {
|
|
52
|
+
orgId,
|
|
53
|
+
userId,
|
|
54
|
+
count: page.rows.length
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
...page,
|
|
58
|
+
page: query.page,
|
|
59
|
+
pageSize: query.pageSize
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async markNotificationRead(orgId, userId, notificationId) {
|
|
63
|
+
const row = await this.repo.markRead(orgId, userId, notificationId, /* @__PURE__ */ new Date());
|
|
64
|
+
if (!row) throw new NotFoundError("Notification", notificationId);
|
|
65
|
+
return row;
|
|
66
|
+
}
|
|
67
|
+
async markAllNotificationsRead(orgId, userId) {
|
|
68
|
+
const updated = await this.repo.markAllRead(orgId, userId, /* @__PURE__ */ new Date());
|
|
69
|
+
this.logger.debug("notifications marked read", {
|
|
70
|
+
orgId,
|
|
71
|
+
userId,
|
|
72
|
+
updated
|
|
73
|
+
});
|
|
74
|
+
return { updated };
|
|
75
|
+
}
|
|
76
|
+
async notificationPreferences(orgId, userId) {
|
|
77
|
+
const stored = await this.repo.preferences(orgId, [userId]);
|
|
78
|
+
const byKind = new Map(stored.map((row) => [row.kind, row]));
|
|
79
|
+
return notificationKindSchema.options.map((kind) => {
|
|
80
|
+
const row = byKind.get(kind);
|
|
81
|
+
return row ? {
|
|
82
|
+
kind,
|
|
83
|
+
inApp: row.inApp,
|
|
84
|
+
email: row.email
|
|
85
|
+
} : defaultPreference(kind);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async setNotificationPreferences(orgId, userId, preferences) {
|
|
89
|
+
await this.repo.upsertPreferences(orgId, userId, preferences);
|
|
90
|
+
this.logger.info("notification preferences updated", {
|
|
91
|
+
orgId,
|
|
92
|
+
userId,
|
|
93
|
+
kinds: preferences.map((pref) => pref.kind)
|
|
94
|
+
});
|
|
95
|
+
return this.notificationPreferences(orgId, userId);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
//#endregion
|
|
99
|
+
export { NotificationServiceImpl, defaultPreference };
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=notifications.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifications.js","names":[],"sources":["../../src/identity/notifications.ts"],"sourcesContent":["import { NotFoundError } from '../shared/errors.js';\nimport { genId } from '../shared/id.js';\nimport { noopLogger } from '../shared/logger.js';\nimport type { Logger } from '../shared/ports.js';\nimport { notificationKindSchema } from '../types/schemas/identity.js';\nimport type { Notification, NotificationKind, NotificationPreference } from './model.js';\nimport type {\n NewNotification,\n NotificationPage,\n NotificationService,\n NotificationsQuery,\n NotificationsRepository,\n} from './ports.js';\n\nexport function defaultPreference(kind: NotificationKind): NotificationPreference {\n return { kind, inApp: true, email: true };\n}\n\nexport class NotificationServiceImpl implements NotificationService {\n private readonly repo: NotificationsRepository;\n private readonly logger: Logger;\n\n constructor(params: { repo: NotificationsRepository; logger?: Logger }) {\n this.repo = params.repo;\n this.logger = params.logger ?? noopLogger;\n }\n\n async notify(orgId: string, notifications: NewNotification[]): Promise<void> {\n if (notifications.length === 0) {\n return;\n }\n const now = new Date();\n const rows: Notification[] = notifications.map((notification) => ({\n ...notification,\n orgId,\n id: genId('notification'),\n createdAt: now,\n readAt: null,\n }));\n await this.repo.insert(orgId, rows);\n this.logger.info('notifications added', {\n orgId,\n kinds: [...new Set(rows.map((row) => row.kind))],\n count: rows.length,\n });\n }\n\n async preferencesFor(\n orgId: string,\n userIds: string[],\n kind: NotificationKind,\n ): Promise<Record<string, NotificationPreference>> {\n const unique = [...new Set(userIds)];\n const stored = await this.repo.preferences(orgId, unique);\n const result: Record<string, NotificationPreference> = {};\n for (const userId of unique) {\n result[userId] = defaultPreference(kind);\n }\n for (const row of stored) {\n if (row.kind === kind) {\n result[row.userId] = { kind, inApp: row.inApp, email: row.email };\n }\n }\n return result;\n }\n\n async listNotifications(\n orgId: string,\n userId: string,\n query: NotificationsQuery,\n ): Promise<NotificationPage> {\n const page = await this.repo.page(orgId, userId, query);\n this.logger.debug('notifications listed', { orgId, userId, count: page.rows.length });\n return { ...page, page: query.page, pageSize: query.pageSize };\n }\n\n async markNotificationRead(\n orgId: string,\n userId: string,\n notificationId: string,\n ): Promise<Notification> {\n const row = await this.repo.markRead(orgId, userId, notificationId, new Date());\n if (!row) {\n throw new NotFoundError('Notification', notificationId);\n }\n return row;\n }\n\n async markAllNotificationsRead(orgId: string, userId: string): Promise<{ updated: number }> {\n const updated = await this.repo.markAllRead(orgId, userId, new Date());\n this.logger.debug('notifications marked read', { orgId, userId, updated });\n return { updated };\n }\n\n async notificationPreferences(orgId: string, userId: string): Promise<NotificationPreference[]> {\n const stored = await this.repo.preferences(orgId, [userId]);\n const byKind = new Map(stored.map((row) => [row.kind, row]));\n return notificationKindSchema.options.map((kind) => {\n const row = byKind.get(kind);\n return row ? { kind, inApp: row.inApp, email: row.email } : defaultPreference(kind);\n });\n }\n\n async setNotificationPreferences(\n orgId: string,\n userId: string,\n preferences: NotificationPreference[],\n ): Promise<NotificationPreference[]> {\n await this.repo.upsertPreferences(orgId, userId, preferences);\n this.logger.info('notification preferences updated', {\n orgId,\n userId,\n kinds: preferences.map((pref) => pref.kind),\n });\n return this.notificationPreferences(orgId, userId);\n }\n}\n"],"mappings":";;;;;AAcA,SAAgB,kBAAkB,MAAgD;CAChF,OAAO;EAAE;EAAM,OAAO;EAAM,OAAO;CAAK;AAC1C;AAEA,IAAa,0BAAb,MAAoE;CAClE;CACA;CAEA,YAAY,QAA4D;EACtE,KAAK,OAAO,OAAO;EACnB,KAAK,SAAS,OAAO,UAAU;CACjC;CAEA,MAAM,OAAO,OAAe,eAAiD;EAC3E,IAAI,cAAc,WAAW,GAC3B;EAEF,MAAM,sBAAM,IAAI,KAAK;EACrB,MAAM,OAAuB,cAAc,KAAK,kBAAkB;GAChE,GAAG;GACH;GACA,IAAI,MAAM,cAAc;GACxB,WAAW;GACX,QAAQ;EACV,EAAE;EACF,MAAM,KAAK,KAAK,OAAO,OAAO,IAAI;EAClC,KAAK,OAAO,KAAK,uBAAuB;GACtC;GACA,OAAO,CAAC,GAAG,IAAI,IAAI,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC;GAC/C,OAAO,KAAK;EACd,CAAC;CACH;CAEA,MAAM,eACJ,OACA,SACA,MACiD;EACjD,MAAM,SAAS,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC;EACnC,MAAM,SAAS,MAAM,KAAK,KAAK,YAAY,OAAO,MAAM;EACxD,MAAM,SAAiD,CAAC;EACxD,KAAK,MAAM,UAAU,QACnB,OAAO,UAAU,kBAAkB,IAAI;EAEzC,KAAK,MAAM,OAAO,QAChB,IAAI,IAAI,SAAS,MACf,OAAO,IAAI,UAAU;GAAE;GAAM,OAAO,IAAI;GAAO,OAAO,IAAI;EAAM;EAGpE,OAAO;CACT;CAEA,MAAM,kBACJ,OACA,QACA,OAC2B;EAC3B,MAAM,OAAO,MAAM,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK;EACtD,KAAK,OAAO,MAAM,wBAAwB;GAAE;GAAO;GAAQ,OAAO,KAAK,KAAK;EAAO,CAAC;EACpF,OAAO;GAAE,GAAG;GAAM,MAAM,MAAM;GAAM,UAAU,MAAM;EAAS;CAC/D;CAEA,MAAM,qBACJ,OACA,QACA,gBACuB;EACvB,MAAM,MAAM,MAAM,KAAK,KAAK,SAAS,OAAO,QAAQ,gCAAgB,IAAI,KAAK,CAAC;EAC9E,IAAI,CAAC,KACH,MAAM,IAAI,cAAc,gBAAgB,cAAc;EAExD,OAAO;CACT;CAEA,MAAM,yBAAyB,OAAe,QAA8C;EAC1F,MAAM,UAAU,MAAM,KAAK,KAAK,YAAY,OAAO,wBAAQ,IAAI,KAAK,CAAC;EACrE,KAAK,OAAO,MAAM,6BAA6B;GAAE;GAAO;GAAQ;EAAQ,CAAC;EACzE,OAAO,EAAE,QAAQ;CACnB;CAEA,MAAM,wBAAwB,OAAe,QAAmD;EAC9F,MAAM,SAAS,MAAM,KAAK,KAAK,YAAY,OAAO,CAAC,MAAM,CAAC;EAC1D,MAAM,SAAS,IAAI,IAAI,OAAO,KAAK,QAAQ,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC;EAC3D,OAAO,uBAAuB,QAAQ,KAAK,SAAS;GAClD,MAAM,MAAM,OAAO,IAAI,IAAI;GAC3B,OAAO,MAAM;IAAE;IAAM,OAAO,IAAI;IAAO,OAAO,IAAI;GAAM,IAAI,kBAAkB,IAAI;EACpF,CAAC;CACH;CAEA,MAAM,2BACJ,OACA,QACA,aACmC;EACnC,MAAM,KAAK,KAAK,kBAAkB,OAAO,QAAQ,WAAW;EAC5D,KAAK,OAAO,KAAK,oCAAoC;GACnD;GACA;GACA,OAAO,YAAY,KAAK,SAAS,KAAK,IAAI;EAC5C,CAAC;EACD,OAAO,KAAK,wBAAwB,OAAO,MAAM;CACnD;AACF"}
|
package/dist/identity/ports.d.ts
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { JsonValue } from "../types/shared.js";
|
|
2
|
+
import { CreateUserInput, Notification, NotificationKind, NotificationPreference, UpdateUserInput, UserProfile, UserProfileView } from "../types/schemas/identity.js";
|
|
2
3
|
import { User } from "../types/identity.js";
|
|
4
|
+
import "../types/index.js";
|
|
3
5
|
import { OutboxAppender, UnitOfWork } from "../shared/ports.js";
|
|
4
6
|
import "./model.js";
|
|
5
7
|
import "./types.js";
|
|
6
8
|
//#region src/identity/ports.d.ts
|
|
9
|
+
interface UpdateProfileInput {
|
|
10
|
+
displayName?: string | null;
|
|
11
|
+
headline?: string | null;
|
|
12
|
+
bio?: string | null;
|
|
13
|
+
imageAssetId?: string | null;
|
|
14
|
+
extra?: JsonValue;
|
|
15
|
+
}
|
|
16
|
+
interface ProfilePatch extends UpdateProfileInput {
|
|
17
|
+
imageAssetOrgId?: string | null;
|
|
18
|
+
}
|
|
7
19
|
interface UserProvisioner {
|
|
8
20
|
createUser(input: CreateUserInput): Promise<User>;
|
|
9
21
|
/** Auth signup entry point. Claims a person provisioned at invite time by
|
|
@@ -14,6 +26,9 @@ interface UserProvisioner {
|
|
|
14
26
|
email: string;
|
|
15
27
|
url: string;
|
|
16
28
|
}): Promise<void>;
|
|
29
|
+
sendPasswordChanged(input: {
|
|
30
|
+
email: string;
|
|
31
|
+
}): Promise<void>;
|
|
17
32
|
sendMagicLink(input: {
|
|
18
33
|
email: string;
|
|
19
34
|
url: string;
|
|
@@ -40,13 +55,71 @@ interface SessionAdmin {
|
|
|
40
55
|
/** Points the caller's current session at `orgId`. */
|
|
41
56
|
stampActiveOrganization(headers: AuthHeaders, orgId: string): Promise<boolean>;
|
|
42
57
|
}
|
|
43
|
-
interface
|
|
58
|
+
interface NewNotification {
|
|
59
|
+
userId: string;
|
|
60
|
+
kind: NotificationKind;
|
|
61
|
+
actorOrgUserId: string | null;
|
|
62
|
+
communityId: string | null;
|
|
63
|
+
spaceId: string | null;
|
|
64
|
+
postId: string | null;
|
|
65
|
+
commentId: string | null;
|
|
66
|
+
chatId: string | null;
|
|
67
|
+
messageId: string | null;
|
|
68
|
+
}
|
|
69
|
+
interface NotificationsQuery {
|
|
70
|
+
page: number;
|
|
71
|
+
pageSize: number;
|
|
72
|
+
}
|
|
73
|
+
interface NotificationPage {
|
|
74
|
+
rows: Notification[];
|
|
75
|
+
total: number;
|
|
76
|
+
page: number;
|
|
77
|
+
pageSize: number;
|
|
78
|
+
unreadCount: number;
|
|
79
|
+
}
|
|
80
|
+
/** What automations calls to tell people. */
|
|
81
|
+
interface NotificationDesk {
|
|
82
|
+
notify(orgId: string, notifications: NewNotification[]): Promise<void>;
|
|
83
|
+
preferencesFor(orgId: string, userIds: string[], kind: NotificationKind): Promise<Record<string, NotificationPreference>>;
|
|
84
|
+
}
|
|
85
|
+
/** A person's own notifications and preferences. */
|
|
86
|
+
interface NotificationInbox {
|
|
87
|
+
listNotifications(orgId: string, userId: string, query: NotificationsQuery): Promise<NotificationPage>;
|
|
88
|
+
markNotificationRead(orgId: string, userId: string, notificationId: string): Promise<Notification>;
|
|
89
|
+
markAllNotificationsRead(orgId: string, userId: string): Promise<{
|
|
90
|
+
updated: number;
|
|
91
|
+
}>;
|
|
92
|
+
notificationPreferences(orgId: string, userId: string): Promise<NotificationPreference[]>;
|
|
93
|
+
setNotificationPreferences(orgId: string, userId: string, preferences: NotificationPreference[]): Promise<NotificationPreference[]>;
|
|
94
|
+
}
|
|
95
|
+
interface NotificationService extends NotificationDesk, NotificationInbox {}
|
|
96
|
+
interface IdentityService extends UserProvisioner, UserResolver, UserEditor {
|
|
97
|
+
profileOf(orgId: string, userId: string): Promise<UserProfileView>;
|
|
98
|
+
displayName(userId: string | null): Promise<string>;
|
|
99
|
+
updateProfile(orgId: string, userId: string, actorUserId: string, orgUserId: string, patch: UpdateProfileInput): Promise<UserProfileView>;
|
|
100
|
+
}
|
|
44
101
|
interface IdentityRepository {
|
|
45
102
|
insertUser(input: CreateUserInput): Promise<User>;
|
|
46
103
|
updateUser(id: string, input: UpdateUserInput): Promise<User | null>;
|
|
47
104
|
findUserById(id: string): Promise<User | null>;
|
|
48
105
|
findUserByExternalId(externalId: string): Promise<User | null>;
|
|
49
106
|
findUserByEmail(email: string): Promise<User | null>;
|
|
107
|
+
findProfile(userId: string): Promise<UserProfile | null>;
|
|
108
|
+
upsertProfile(userId: string, patch: ProfilePatch): Promise<UserProfile>;
|
|
109
|
+
}
|
|
110
|
+
interface NotificationsRepository {
|
|
111
|
+
insert(orgId: string, rows: Notification[]): Promise<void>;
|
|
112
|
+
page(orgId: string, userId: string, query: NotificationsQuery): Promise<{
|
|
113
|
+
rows: Notification[];
|
|
114
|
+
total: number;
|
|
115
|
+
unreadCount: number;
|
|
116
|
+
}>;
|
|
117
|
+
markRead(orgId: string, userId: string, notificationId: string, at: Date): Promise<Notification | null>;
|
|
118
|
+
markAllRead(orgId: string, userId: string, at: Date): Promise<number>;
|
|
119
|
+
preferences(orgId: string, userIds: string[]): Promise<(NotificationPreference & {
|
|
120
|
+
userId: string;
|
|
121
|
+
})[]>;
|
|
122
|
+
upsertPreferences(orgId: string, userId: string, preferences: NotificationPreference[]): Promise<void>;
|
|
50
123
|
}
|
|
51
124
|
interface IdentityTxScope {
|
|
52
125
|
identity: IdentityRepository;
|
|
@@ -54,5 +127,5 @@ interface IdentityTxScope {
|
|
|
54
127
|
}
|
|
55
128
|
type IdentityUnitOfWork = UnitOfWork<IdentityTxScope>;
|
|
56
129
|
//#endregion
|
|
57
|
-
export { AuthHeaders, IdentityRepository, IdentityService, IdentityTxScope, IdentityUnitOfWork, SessionAdmin, UserEditor, UserProvisioner, UserResolver };
|
|
130
|
+
export { AuthHeaders, IdentityRepository, IdentityService, IdentityTxScope, IdentityUnitOfWork, NewNotification, NotificationDesk, NotificationInbox, NotificationPage, NotificationService, NotificationsQuery, NotificationsRepository, ProfilePatch, SessionAdmin, UpdateProfileInput, UserEditor, UserProvisioner, UserResolver };
|
|
58
131
|
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
import { Logger } from "../types/ports.js";
|
|
2
|
-
import { CreateUserInput, UpdateUserInput } from "../types/schemas/identity.js";
|
|
2
|
+
import { CreateUserInput, UpdateUserInput, UserProfileView } from "../types/schemas/identity.js";
|
|
3
3
|
import { User } from "../types/identity.js";
|
|
4
4
|
import "../shared/ports.js";
|
|
5
|
-
import {
|
|
5
|
+
import { FileUrls } from "../assets/file-urls.js";
|
|
6
|
+
import { MemberImageReader } from "../assets/ports.js";
|
|
7
|
+
import "../assets/index.js";
|
|
6
8
|
import "./model.js";
|
|
7
9
|
import "./types.js";
|
|
8
|
-
import { IdentityRepository, IdentityService, IdentityUnitOfWork } from "./ports.js";
|
|
10
|
+
import { IdentityRepository, IdentityService, IdentityUnitOfWork, UpdateProfileInput } from "./ports.js";
|
|
11
|
+
import { Mailer } from "../shared/mailer.js";
|
|
9
12
|
//#region src/identity/service.d.ts
|
|
10
13
|
declare class IdentityServiceImpl implements IdentityService {
|
|
11
14
|
private readonly repo;
|
|
12
15
|
private readonly logger;
|
|
13
16
|
private readonly uow;
|
|
14
17
|
private readonly mailer;
|
|
18
|
+
private readonly images;
|
|
19
|
+
private readonly fileUrls;
|
|
15
20
|
constructor(input: {
|
|
16
21
|
repo: IdentityRepository;
|
|
17
22
|
logger?: Logger;
|
|
18
23
|
mailer: Mailer;
|
|
19
24
|
uow: IdentityUnitOfWork;
|
|
25
|
+
images: MemberImageReader;
|
|
26
|
+
fileUrls: FileUrls;
|
|
20
27
|
});
|
|
21
28
|
createUser(input: CreateUserInput): Promise<User>;
|
|
22
29
|
linkOrCreateUser(input: CreateUserInput): Promise<User>;
|
|
@@ -28,10 +35,17 @@ declare class IdentityServiceImpl implements IdentityService {
|
|
|
28
35
|
email: string;
|
|
29
36
|
url: string;
|
|
30
37
|
}): Promise<void>;
|
|
38
|
+
sendPasswordChanged(input: {
|
|
39
|
+
email: string;
|
|
40
|
+
}): Promise<void>;
|
|
31
41
|
sendMagicLink(input: {
|
|
32
42
|
email: string;
|
|
33
43
|
url: string;
|
|
34
44
|
}): Promise<void>;
|
|
45
|
+
profileOf(orgId: string, userId: string): Promise<UserProfileView>;
|
|
46
|
+
private view;
|
|
47
|
+
displayName(userId: string | null): Promise<string>;
|
|
48
|
+
updateProfile(orgId: string, userId: string, actorUserId: string, orgUserId: string, patch: UpdateProfileInput): Promise<UserProfileView>;
|
|
35
49
|
}
|
|
36
50
|
//#endregion
|
|
37
51
|
export { IdentityServiceImpl };
|
package/dist/identity/service.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
|
+
import { genId } from "../shared/id.js";
|
|
2
|
+
import { ConflictError, ForbiddenError, NotFoundError } from "../shared/errors.js";
|
|
1
3
|
import { noopLogger } from "../shared/logger.js";
|
|
2
|
-
import { ConflictError, NotFoundError } from "../shared/errors.js";
|
|
3
4
|
import { identityEvents } from "./events.js";
|
|
4
5
|
//#region src/identity/service.ts
|
|
6
|
+
const UNNAMED = "A member";
|
|
5
7
|
var IdentityServiceImpl = class {
|
|
6
8
|
repo;
|
|
7
9
|
logger;
|
|
8
10
|
uow;
|
|
9
11
|
mailer;
|
|
12
|
+
images;
|
|
13
|
+
fileUrls;
|
|
10
14
|
constructor(input) {
|
|
11
15
|
this.repo = input.repo;
|
|
12
16
|
this.mailer = input.mailer;
|
|
13
17
|
this.logger = input.logger ?? noopLogger;
|
|
14
18
|
this.uow = input.uow;
|
|
19
|
+
this.images = input.images;
|
|
20
|
+
this.fileUrls = input.fileUrls;
|
|
15
21
|
}
|
|
16
22
|
async createUser(input) {
|
|
17
23
|
const created = await this.uow.run(async ({ identity, outbox }) => {
|
|
@@ -22,12 +28,19 @@ var IdentityServiceImpl = class {
|
|
|
22
28
|
})]);
|
|
23
29
|
return user;
|
|
24
30
|
});
|
|
25
|
-
this.logger.info("user created", {
|
|
31
|
+
this.logger.info("user created", { userId: created.id });
|
|
26
32
|
return created;
|
|
27
33
|
}
|
|
28
34
|
async linkOrCreateUser(input) {
|
|
29
35
|
const existing = await this.repo.findUserByEmail(input.email);
|
|
30
|
-
if (!existing)
|
|
36
|
+
if (!existing) {
|
|
37
|
+
const id = input.id ?? genId("user");
|
|
38
|
+
return this.createUser({
|
|
39
|
+
...input,
|
|
40
|
+
id,
|
|
41
|
+
externalId: id
|
|
42
|
+
});
|
|
43
|
+
}
|
|
31
44
|
if (existing.externalId !== null) throw new ConflictError("That email already has an account");
|
|
32
45
|
const linked = await this.uow.run(async ({ identity, outbox }) => {
|
|
33
46
|
const user = await identity.updateUser(existing.id, {
|
|
@@ -41,7 +54,7 @@ var IdentityServiceImpl = class {
|
|
|
41
54
|
})]);
|
|
42
55
|
return user;
|
|
43
56
|
});
|
|
44
|
-
this.logger.info("user linked to auth account", {
|
|
57
|
+
this.logger.info("user linked to auth account", { userId: linked.id });
|
|
45
58
|
return linked;
|
|
46
59
|
}
|
|
47
60
|
async updateUser(id, input) {
|
|
@@ -54,7 +67,7 @@ var IdentityServiceImpl = class {
|
|
|
54
67
|
})]);
|
|
55
68
|
return user;
|
|
56
69
|
});
|
|
57
|
-
this.logger.info("user updated", {
|
|
70
|
+
this.logger.info("user updated", { userId: updated.id });
|
|
58
71
|
return updated;
|
|
59
72
|
}
|
|
60
73
|
async getUserByExternalId(externalId) {
|
|
@@ -69,9 +82,64 @@ var IdentityServiceImpl = class {
|
|
|
69
82
|
async sendPasswordReset(input) {
|
|
70
83
|
await this.mailer.send(input.email, "passwordReset", { resetUrl: input.url });
|
|
71
84
|
}
|
|
85
|
+
async sendPasswordChanged(input) {
|
|
86
|
+
await this.mailer.send(input.email, "passwordChanged", {});
|
|
87
|
+
}
|
|
72
88
|
async sendMagicLink(input) {
|
|
73
89
|
await this.mailer.send(input.email, "magicLink", { url: input.url });
|
|
74
90
|
}
|
|
91
|
+
async profileOf(orgId, userId) {
|
|
92
|
+
const stored = await this.repo.findProfile(userId);
|
|
93
|
+
if (stored) return this.view(orgId, stored);
|
|
94
|
+
const never = /* @__PURE__ */ new Date(0);
|
|
95
|
+
return {
|
|
96
|
+
userId,
|
|
97
|
+
displayName: null,
|
|
98
|
+
headline: null,
|
|
99
|
+
bio: null,
|
|
100
|
+
imageAssetOrgId: null,
|
|
101
|
+
imageAssetId: null,
|
|
102
|
+
imageUrl: null,
|
|
103
|
+
extra: {},
|
|
104
|
+
createdAt: never,
|
|
105
|
+
updatedAt: never
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
view(orgId, profile) {
|
|
109
|
+
const imageAssetId = profile.imageAssetOrgId === orgId ? profile.imageAssetId : null;
|
|
110
|
+
return {
|
|
111
|
+
...profile,
|
|
112
|
+
imageUrl: imageAssetId ? this.fileUrls.memberUpload(imageAssetId) : null
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
async displayName(userId) {
|
|
116
|
+
if (userId === null) return UNNAMED;
|
|
117
|
+
const [profile, user] = await Promise.all([this.repo.findProfile(userId), this.repo.findUserById(userId)]);
|
|
118
|
+
const named = profile?.displayName?.trim();
|
|
119
|
+
if (named) return named;
|
|
120
|
+
return [user?.firstName, user?.lastName].filter(Boolean).join(" ").trim() || UNNAMED;
|
|
121
|
+
}
|
|
122
|
+
async updateProfile(orgId, userId, actorUserId, orgUserId, patch) {
|
|
123
|
+
if (actorUserId !== userId) throw new ForbiddenError("You can only update your own profile");
|
|
124
|
+
if (!await this.repo.findUserById(userId)) throw new NotFoundError("User", userId);
|
|
125
|
+
if (patch.imageAssetId != null) {
|
|
126
|
+
if (!await this.images.ownsImage(orgId, patch.imageAssetId, orgUserId)) {
|
|
127
|
+
this.logger.debug("profile photo refused", {
|
|
128
|
+
userId,
|
|
129
|
+
orgUserId,
|
|
130
|
+
assetId: patch.imageAssetId
|
|
131
|
+
});
|
|
132
|
+
throw new NotFoundError("Asset", patch.imageAssetId);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const imageAssetOrgId = patch.imageAssetId === void 0 ? void 0 : patch.imageAssetId === null ? null : orgId;
|
|
136
|
+
const profile = await this.repo.upsertProfile(userId, {
|
|
137
|
+
...patch,
|
|
138
|
+
imageAssetOrgId
|
|
139
|
+
});
|
|
140
|
+
this.logger.info("profile updated", { userId });
|
|
141
|
+
return this.view(orgId, profile);
|
|
142
|
+
}
|
|
75
143
|
};
|
|
76
144
|
//#endregion
|
|
77
145
|
export { IdentityServiceImpl };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","names":[],"sources":["../../src/identity/service.ts"],"sourcesContent":["import type { IdentityRepository, IdentityService, IdentityUnitOfWork } from './ports.js';\nimport type { User } from './model.js';\nimport type { CreateUserInput, UpdateUserInput } from './types.js';\nimport type { Logger } from '../shared/ports.js';\nimport { noopLogger } from '../shared/logger.js';\nimport { ConflictError, NotFoundError } from '../shared/errors.js';\nimport type { Mailer } from '../shared/mailer.js';\nimport { identityEvents } from './events.js';\n\nexport class IdentityServiceImpl implements IdentityService {\n private readonly repo: IdentityRepository;\n private readonly logger: Logger;\n private readonly uow: IdentityUnitOfWork;\n private readonly mailer: Pick<Mailer, 'send'>;\n\n constructor(input: {\n repo: IdentityRepository;\n logger?: Logger;\n mailer: Mailer;\n uow: IdentityUnitOfWork;\n }) {\n this.repo = input.repo;\n this.mailer = input.mailer;\n this.logger = input.logger ?? noopLogger;\n this.uow = input.uow;\n }\n\n async createUser(input: CreateUserInput): Promise<User> {\n const created = await this.uow.run(async ({ identity, outbox }) => {\n const user = await identity.insertUser(input);\n await outbox.append([
|
|
1
|
+
{"version":3,"file":"service.js","names":[],"sources":["../../src/identity/service.ts"],"sourcesContent":["import type { IdentityRepository, IdentityService, IdentityUnitOfWork } from './ports.js';\nimport type { User, UserProfile, UserProfileView } from './model.js';\nimport type { UpdateProfileInput } from './ports.js';\nimport type { CreateUserInput, UpdateUserInput } from './types.js';\nimport type { Logger } from '../shared/ports.js';\nimport { noopLogger } from '../shared/logger.js';\nimport { genId } from '../shared/id.js';\nimport { ConflictError, ForbiddenError, NotFoundError } from '../shared/errors.js';\nimport type { Mailer } from '../shared/mailer.js';\nimport type { FileUrls, MemberImageReader } from '../assets/index.js';\nimport { identityEvents } from './events.js';\n\nconst UNNAMED = 'A member';\n\nexport class IdentityServiceImpl implements IdentityService {\n private readonly repo: IdentityRepository;\n private readonly logger: Logger;\n private readonly uow: IdentityUnitOfWork;\n private readonly mailer: Pick<Mailer, 'send'>;\n private readonly images: MemberImageReader;\n private readonly fileUrls: FileUrls;\n\n constructor(input: {\n repo: IdentityRepository;\n logger?: Logger;\n mailer: Mailer;\n uow: IdentityUnitOfWork;\n images: MemberImageReader;\n fileUrls: FileUrls;\n }) {\n this.repo = input.repo;\n this.mailer = input.mailer;\n this.logger = input.logger ?? noopLogger;\n this.uow = input.uow;\n this.images = input.images;\n this.fileUrls = input.fileUrls;\n }\n\n async createUser(input: CreateUserInput): Promise<User> {\n const created = await this.uow.run(async ({ identity, outbox }) => {\n const user = await identity.insertUser(input);\n await outbox.append([identityEvents.userCreated.make({ orgId: '-', data: user })]);\n return user;\n });\n this.logger.info('user created', { userId: created.id });\n return created;\n }\n\n async linkOrCreateUser(input: CreateUserInput): Promise<User> {\n const existing = await this.repo.findUserByEmail(input.email);\n if (!existing) {\n const id = input.id ?? genId('user');\n return this.createUser({ ...input, id, externalId: id });\n }\n if (existing.externalId !== null) {\n throw new ConflictError('That email already has an account');\n }\n // Existing user without external link, so invited. update the user with the\n // id.\n const linked = await this.uow.run(async ({ identity, outbox }) => {\n const user = await identity.updateUser(existing.id, {\n externalId: existing.id,\n ...(input.firstName !== undefined && { firstName: input.firstName }),\n ...(input.lastName !== undefined && { lastName: input.lastName }),\n });\n await outbox.append([identityEvents.userUpdated.make({ orgId: '-', data: user! })]);\n return user!;\n });\n this.logger.info('user linked to auth account', { userId: linked.id });\n return linked;\n }\n\n async updateUser(id: string, input: UpdateUserInput): Promise<User> {\n const person = await this.repo.findUserById(id);\n if (!person) {\n throw new NotFoundError('User', id);\n }\n\n const updated = await this.uow.run(async ({ identity, outbox }) => {\n const user = await identity.updateUser(id, input);\n await outbox.append([identityEvents.userUpdated.make({ orgId: '-', data: user! })]);\n return user!;\n });\n this.logger.info('user updated', { userId: updated.id });\n return updated;\n }\n\n async getUserByExternalId(externalId: string): Promise<User | null> {\n return this.repo.findUserByExternalId(externalId);\n }\n\n async getUserByEmail(email: string): Promise<User | null> {\n return this.repo.findUserByEmail(email);\n }\n\n async getUserById(id: string): Promise<User | null> {\n return this.repo.findUserById(id);\n }\n\n async sendPasswordReset(input: { email: string; url: string }): Promise<void> {\n await this.mailer.send(input.email, 'passwordReset', { resetUrl: input.url });\n }\n\n async sendPasswordChanged(input: { email: string }): Promise<void> {\n await this.mailer.send(input.email, 'passwordChanged', {});\n }\n\n async sendMagicLink(input: { email: string; url: string }): Promise<void> {\n await this.mailer.send(input.email, 'magicLink', { url: input.url });\n }\n\n async profileOf(orgId: string, userId: string): Promise<UserProfileView> {\n const stored = await this.repo.findProfile(userId);\n if (stored) {\n return this.view(orgId, stored);\n }\n const never = new Date(0);\n return {\n userId,\n displayName: null,\n headline: null,\n bio: null,\n imageAssetOrgId: null,\n imageAssetId: null,\n imageUrl: null,\n extra: {},\n createdAt: never,\n updatedAt: never,\n };\n }\n\n private view(orgId: string, profile: UserProfile): UserProfileView {\n const imageAssetId = profile.imageAssetOrgId === orgId ? profile.imageAssetId : null;\n return { ...profile, imageUrl: imageAssetId ? this.fileUrls.memberUpload(imageAssetId) : null };\n }\n\n async displayName(userId: string | null): Promise<string> {\n if (userId === null) {\n return UNNAMED;\n }\n const [profile, user] = await Promise.all([\n this.repo.findProfile(userId),\n this.repo.findUserById(userId),\n ]);\n const named = profile?.displayName?.trim();\n if (named) {\n return named;\n }\n const composed = [user?.firstName, user?.lastName].filter(Boolean).join(' ').trim();\n return composed || UNNAMED;\n }\n\n async updateProfile(\n orgId: string,\n userId: string,\n actorUserId: string,\n orgUserId: string,\n patch: UpdateProfileInput,\n ): Promise<UserProfileView> {\n if (actorUserId !== userId) {\n throw new ForbiddenError('You can only update your own profile');\n }\n const user = await this.repo.findUserById(userId);\n if (!user) {\n throw new NotFoundError('User', userId);\n }\n if (patch.imageAssetId != null) {\n const owned = await this.images.ownsImage(orgId, patch.imageAssetId, orgUserId);\n if (!owned) {\n this.logger.debug('profile photo refused', {\n userId,\n orgUserId,\n assetId: patch.imageAssetId,\n });\n throw new NotFoundError('Asset', patch.imageAssetId);\n }\n }\n const imageAssetOrgId =\n patch.imageAssetId === undefined ? undefined : patch.imageAssetId === null ? null : orgId;\n const profile = await this.repo.upsertProfile(userId, { ...patch, imageAssetOrgId });\n this.logger.info('profile updated', { userId });\n return this.view(orgId, profile);\n }\n}\n"],"mappings":"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"}
|
|
@@ -21,7 +21,15 @@ declare const integrationEvents: {
|
|
|
21
21
|
credentialRef: string;
|
|
22
22
|
createdAt: unknown;
|
|
23
23
|
updatedAt: unknown;
|
|
24
|
-
}
|
|
24
|
+
}, import("zod").ZodObject<{
|
|
25
|
+
orgId: import("zod").ZodString;
|
|
26
|
+
id: import("zod").ZodString;
|
|
27
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
28
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
29
|
+
active: import("zod").ZodBoolean;
|
|
30
|
+
integrationId: import("zod").ZodString;
|
|
31
|
+
config: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodType<JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<JsonValue, unknown>>>;
|
|
32
|
+
}, import("zod/v4/core").$strip>>;
|
|
25
33
|
connectionUpdated: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
26
34
|
orgId: string;
|
|
27
35
|
id: string;
|
|
@@ -40,7 +48,15 @@ declare const integrationEvents: {
|
|
|
40
48
|
credentialRef: string;
|
|
41
49
|
createdAt: unknown;
|
|
42
50
|
updatedAt: unknown;
|
|
43
|
-
}
|
|
51
|
+
}, import("zod").ZodObject<{
|
|
52
|
+
orgId: import("zod").ZodString;
|
|
53
|
+
id: import("zod").ZodString;
|
|
54
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
55
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
56
|
+
active: import("zod").ZodBoolean;
|
|
57
|
+
integrationId: import("zod").ZodString;
|
|
58
|
+
config: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodType<JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<JsonValue, unknown>>>;
|
|
59
|
+
}, import("zod/v4/core").$strip>>;
|
|
44
60
|
connectionRemoved: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
45
61
|
orgId: string;
|
|
46
62
|
id: string;
|
|
@@ -59,7 +75,15 @@ declare const integrationEvents: {
|
|
|
59
75
|
credentialRef: string;
|
|
60
76
|
createdAt: unknown;
|
|
61
77
|
updatedAt: unknown;
|
|
62
|
-
}
|
|
78
|
+
}, import("zod").ZodObject<{
|
|
79
|
+
orgId: import("zod").ZodString;
|
|
80
|
+
id: import("zod").ZodString;
|
|
81
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
82
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
83
|
+
active: import("zod").ZodBoolean;
|
|
84
|
+
integrationId: import("zod").ZodString;
|
|
85
|
+
config: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodType<JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<JsonValue, unknown>>>;
|
|
86
|
+
}, import("zod/v4/core").$strip>>;
|
|
63
87
|
};
|
|
64
88
|
type ConnectionCreated = EventOf<typeof integrationEvents.connectionCreated>;
|
|
65
89
|
type ConnectionUpdated = EventOf<typeof integrationEvents.connectionUpdated>;
|
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
import { connectionSchema } from "../types/schemas/integrations.js";
|
|
2
2
|
import { defineEvent } from "../shared/events.js";
|
|
3
3
|
//#region src/integrations/events.ts
|
|
4
|
+
const publicConnection = connectionSchema.pick({
|
|
5
|
+
orgId: true,
|
|
6
|
+
id: true,
|
|
7
|
+
integrationId: true,
|
|
8
|
+
config: true,
|
|
9
|
+
active: true,
|
|
10
|
+
createdAt: true,
|
|
11
|
+
updatedAt: true
|
|
12
|
+
}).strip();
|
|
4
13
|
const integrationEvents = {
|
|
5
14
|
connectionCreated: defineEvent({
|
|
6
15
|
type: "integration.connection.created",
|
|
7
16
|
version: 1,
|
|
8
|
-
data: connectionSchema
|
|
17
|
+
data: connectionSchema,
|
|
18
|
+
publicData: publicConnection
|
|
9
19
|
}),
|
|
10
20
|
connectionUpdated: defineEvent({
|
|
11
21
|
type: "integration.connection.updated",
|
|
12
22
|
version: 1,
|
|
13
|
-
data: connectionSchema
|
|
23
|
+
data: connectionSchema,
|
|
24
|
+
publicData: publicConnection
|
|
14
25
|
}),
|
|
15
26
|
connectionRemoved: defineEvent({
|
|
16
27
|
type: "integration.connection.removed",
|
|
17
28
|
version: 1,
|
|
18
|
-
data: connectionSchema
|
|
29
|
+
data: connectionSchema,
|
|
30
|
+
publicData: publicConnection
|
|
19
31
|
})
|
|
20
32
|
};
|
|
21
33
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","names":[],"sources":["../../src/integrations/events.ts"],"sourcesContent":["import { connectionSchema } from '../types/schemas/index.js';\nimport { defineEvent, type EventOf, type EventOfValues } from '../shared/ports.js';\n\nexport const integrationEvents = {\n connectionCreated: defineEvent({\n type: 'integration.connection.created',\n version: 1,\n data: connectionSchema,\n }),\n connectionUpdated: defineEvent({\n type: 'integration.connection.updated',\n version: 1,\n data: connectionSchema,\n }),\n connectionRemoved: defineEvent({\n type: 'integration.connection.removed',\n version: 1,\n data: connectionSchema,\n }),\n};\n\nexport type ConnectionCreated = EventOf<typeof integrationEvents.connectionCreated>;\nexport type ConnectionUpdated = EventOf<typeof integrationEvents.connectionUpdated>;\nexport type ConnectionRemoved = EventOf<typeof integrationEvents.connectionRemoved>;\nexport type IntegrationEvent = EventOfValues<typeof integrationEvents>;\n"],"mappings":";;;AAGA,MAAa,oBAAoB;CAC/B,mBAAmB,YAAY;EAC7B,MAAM;EACN,SAAS;EACT,MAAM;
|
|
1
|
+
{"version":3,"file":"events.js","names":[],"sources":["../../src/integrations/events.ts"],"sourcesContent":["import { connectionSchema } from '../types/schemas/index.js';\nimport { defineEvent, type EventOf, type EventOfValues } from '../shared/ports.js';\n\nconst publicConnection = connectionSchema\n .pick({\n orgId: true,\n id: true,\n integrationId: true,\n config: true,\n active: true,\n createdAt: true,\n updatedAt: true,\n })\n .strip();\n\nexport const integrationEvents = {\n connectionCreated: defineEvent({\n type: 'integration.connection.created',\n version: 1,\n data: connectionSchema,\n publicData: publicConnection,\n }),\n connectionUpdated: defineEvent({\n type: 'integration.connection.updated',\n version: 1,\n data: connectionSchema,\n publicData: publicConnection,\n }),\n connectionRemoved: defineEvent({\n type: 'integration.connection.removed',\n version: 1,\n data: connectionSchema,\n publicData: publicConnection,\n }),\n};\n\nexport type ConnectionCreated = EventOf<typeof integrationEvents.connectionCreated>;\nexport type ConnectionUpdated = EventOf<typeof integrationEvents.connectionUpdated>;\nexport type ConnectionRemoved = EventOf<typeof integrationEvents.connectionRemoved>;\nexport type IntegrationEvent = EventOfValues<typeof integrationEvents>;\n"],"mappings":";;;AAGA,MAAM,mBAAmB,iBACtB,KAAK;CACJ,OAAO;CACP,IAAI;CACJ,eAAe;CACf,QAAQ;CACR,QAAQ;CACR,WAAW;CACX,WAAW;AACb,CAAC,CAAC,CACD,MAAM;AAET,MAAa,oBAAoB;CAC/B,mBAAmB,YAAY;EAC7B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,mBAAmB,YAAY;EAC7B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,mBAAmB,YAAY;EAC7B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;AACH"}
|