alepha 0.19.3 → 0.19.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
  2. package/dist/api/audits/index.d.ts +8 -8
  3. package/dist/api/invitations/index.d.ts +790 -0
  4. package/dist/api/invitations/index.d.ts.map +1 -0
  5. package/dist/api/invitations/index.js +665 -0
  6. package/dist/api/invitations/index.js.map +1 -0
  7. package/dist/api/jobs/index.browser.js +8 -9
  8. package/dist/api/jobs/index.browser.js.map +1 -1
  9. package/dist/api/jobs/index.d.ts +99 -43
  10. package/dist/api/jobs/index.d.ts.map +1 -1
  11. package/dist/api/jobs/index.js +257 -40
  12. package/dist/api/jobs/index.js.map +1 -1
  13. package/dist/api/keys/index.d.ts +5 -5
  14. package/dist/api/notifications/index.browser.js +0 -1
  15. package/dist/api/notifications/index.browser.js.map +1 -1
  16. package/dist/api/notifications/index.d.ts +3 -3
  17. package/dist/api/notifications/index.d.ts.map +1 -1
  18. package/dist/api/notifications/index.js +0 -1
  19. package/dist/api/notifications/index.js.map +1 -1
  20. package/dist/api/parameters/index.browser.js +112 -1
  21. package/dist/api/parameters/index.browser.js.map +1 -1
  22. package/dist/api/parameters/index.d.ts +90 -3
  23. package/dist/api/parameters/index.d.ts.map +1 -1
  24. package/dist/api/parameters/index.js +79 -12
  25. package/dist/api/parameters/index.js.map +1 -1
  26. package/dist/{billing → api/payments}/index.d.ts +67 -49
  27. package/dist/api/payments/index.d.ts.map +1 -0
  28. package/dist/{billing → api/payments}/index.js +108 -74
  29. package/dist/api/payments/index.js.map +1 -0
  30. package/dist/api/subscriptions/index.d.ts +1692 -0
  31. package/dist/api/subscriptions/index.d.ts.map +1 -0
  32. package/dist/api/subscriptions/index.js +1870 -0
  33. package/dist/api/subscriptions/index.js.map +1 -0
  34. package/dist/api/users/index.d.ts +18 -2
  35. package/dist/api/users/index.d.ts.map +1 -1
  36. package/dist/api/users/index.js +167 -34
  37. package/dist/api/users/index.js.map +1 -1
  38. package/dist/api/verifications/index.d.ts +13 -13
  39. package/dist/api/workflows/index.browser.js +246 -0
  40. package/dist/api/workflows/index.browser.js.map +1 -0
  41. package/dist/api/workflows/index.d.ts +1618 -0
  42. package/dist/api/workflows/index.d.ts.map +1 -0
  43. package/dist/api/workflows/index.js +1504 -0
  44. package/dist/api/workflows/index.js.map +1 -0
  45. package/dist/cli/core/index.d.ts +44 -28
  46. package/dist/cli/core/index.d.ts.map +1 -1
  47. package/dist/cli/core/index.js +16 -61
  48. package/dist/cli/core/index.js.map +1 -1
  49. package/dist/cli/vendor/index.d.ts +31 -8
  50. package/dist/cli/vendor/index.d.ts.map +1 -1
  51. package/dist/cli/vendor/index.js +79 -24
  52. package/dist/cli/vendor/index.js.map +1 -1
  53. package/dist/core/index.browser.js +21 -2
  54. package/dist/core/index.browser.js.map +1 -1
  55. package/dist/core/index.d.ts +33 -2
  56. package/dist/core/index.d.ts.map +1 -1
  57. package/dist/core/index.js +21 -2
  58. package/dist/core/index.js.map +1 -1
  59. package/dist/core/index.native.js +21 -2
  60. package/dist/core/index.native.js.map +1 -1
  61. package/dist/core/index.workerd.js +21 -2
  62. package/dist/core/index.workerd.js.map +1 -1
  63. package/dist/email/smtp/index.js +24 -8
  64. package/dist/email/smtp/index.js.map +1 -1
  65. package/dist/orm/core/index.browser.js +0 -18
  66. package/dist/orm/core/index.browser.js.map +1 -1
  67. package/dist/orm/core/index.bun.js +0 -17
  68. package/dist/orm/core/index.bun.js.map +1 -1
  69. package/dist/orm/core/index.d.ts +1 -13
  70. package/dist/orm/core/index.d.ts.map +1 -1
  71. package/dist/orm/core/index.js +0 -17
  72. package/dist/orm/core/index.js.map +1 -1
  73. package/dist/orm/postgres/index.bun.js +3 -3
  74. package/dist/orm/postgres/index.bun.js.map +1 -1
  75. package/dist/orm/postgres/index.d.ts.map +1 -1
  76. package/dist/orm/postgres/index.js +3 -3
  77. package/dist/orm/postgres/index.js.map +1 -1
  78. package/dist/react/router/index.browser.js +25 -3
  79. package/dist/react/router/index.browser.js.map +1 -1
  80. package/dist/react/router/index.d.ts +16 -1
  81. package/dist/react/router/index.d.ts.map +1 -1
  82. package/dist/react/router/index.js +25 -3
  83. package/dist/react/router/index.js.map +1 -1
  84. package/dist/security/index.d.ts +28 -0
  85. package/dist/security/index.d.ts.map +1 -1
  86. package/dist/security/index.js +28 -0
  87. package/dist/security/index.js.map +1 -1
  88. package/package.json +37 -20
  89. package/src/api/invitations/__tests__/InvitationService.spec.ts +439 -0
  90. package/src/api/invitations/controllers/AdminInvitationController.ts +86 -0
  91. package/src/api/invitations/controllers/InvitationController.ts +84 -0
  92. package/src/api/invitations/entities/invitations.ts +33 -0
  93. package/src/api/invitations/index.ts +65 -0
  94. package/src/api/invitations/jobs/InvitationJobs.ts +37 -0
  95. package/src/api/invitations/providers/InvitationProvider.ts +45 -0
  96. package/src/api/invitations/schemas/createInvitationSchema.ts +12 -0
  97. package/src/api/invitations/schemas/invitationConfigAtom.ts +20 -0
  98. package/src/api/invitations/schemas/invitationQuerySchema.ts +15 -0
  99. package/src/api/invitations/schemas/invitationResourceSchema.ts +6 -0
  100. package/src/api/invitations/schemas/invitationWithResourceInfoSchema.ts +22 -0
  101. package/src/api/invitations/schemas/myInvitationsQuerySchema.ts +10 -0
  102. package/src/api/invitations/services/InvitationService.ts +556 -0
  103. package/src/api/jobs/__tests__/$job.spec.ts +876 -0
  104. package/src/api/jobs/controllers/AdminJobController.ts +44 -0
  105. package/src/api/jobs/entities/jobExecutionEntity.ts +0 -2
  106. package/src/api/jobs/index.ts +0 -3
  107. package/src/api/jobs/primitives/$job.ts +22 -11
  108. package/src/api/jobs/providers/JobProvider.ts +229 -19
  109. package/src/api/jobs/schemas/jobConfigAtom.ts +4 -0
  110. package/src/api/jobs/schemas/jobCronInfoSchema.ts +1 -0
  111. package/src/api/jobs/schemas/jobExecutionQuerySchema.ts +0 -1
  112. package/src/api/jobs/schemas/jobQueueDepthSchema.ts +1 -0
  113. package/src/api/jobs/schemas/jobRegistrationSchema.ts +1 -6
  114. package/src/api/jobs/services/JobService.ts +51 -12
  115. package/src/api/notifications/schemas/notificationQuerySchema.ts +0 -1
  116. package/src/api/parameters/__tests__/$parameter.spec.ts +327 -0
  117. package/src/api/parameters/controllers/AdminParameterController.ts +29 -3
  118. package/src/api/parameters/index.browser.ts +12 -0
  119. package/src/api/parameters/primitives/$parameter.ts +20 -3
  120. package/src/api/parameters/services/ParameterProvider.ts +48 -7
  121. package/src/{billing → api/payments}/__tests__/PaymentMethodService.spec.ts +32 -6
  122. package/src/api/payments/__tests__/PaymentService.spec.ts +279 -0
  123. package/src/{billing/controllers/AdminBillingController.ts → api/payments/controllers/AdminPaymentController.ts} +26 -21
  124. package/src/{billing/controllers/BillingController.ts → api/payments/controllers/PaymentController.ts} +23 -11
  125. package/src/{billing → api/payments}/entities/paymentIntents.ts +1 -0
  126. package/src/{billing/errors/BillingError.ts → api/payments/errors/PaymentError.ts} +1 -1
  127. package/src/{billing → api/payments}/index.ts +31 -25
  128. package/src/{billing/providers/MemoryBillingProvider.ts → api/payments/providers/MemoryPaymentProvider.ts} +4 -4
  129. package/src/{billing/providers/BillingProvider.ts → api/payments/providers/PaymentProvider.ts} +9 -2
  130. package/src/{billing → api/payments}/services/PaymentMethodService.ts +5 -5
  131. package/src/{billing/services/BillingService.ts → api/payments/services/PaymentService.ts} +94 -18
  132. package/src/api/subscriptions/__tests__/BillingService.spec.ts +218 -0
  133. package/src/api/subscriptions/__tests__/SubscriptionService.spec.ts +278 -0
  134. package/src/api/subscriptions/controllers/AdminSubscriptionController.ts +212 -0
  135. package/src/api/subscriptions/controllers/SubscriptionController.ts +189 -0
  136. package/src/api/subscriptions/entities/subscriptionEvents.ts +54 -0
  137. package/src/api/subscriptions/entities/subscriptions.ts +68 -0
  138. package/src/api/subscriptions/index.ts +144 -0
  139. package/src/api/subscriptions/jobs/SubscriptionJobs.ts +382 -0
  140. package/src/api/subscriptions/middleware/$requireLimit.ts +50 -0
  141. package/src/api/subscriptions/middleware/$requirePlan.ts +49 -0
  142. package/src/api/subscriptions/notifications/SubscriptionNotifications.ts +110 -0
  143. package/src/api/subscriptions/schemas/cancelSubscriptionSchema.ts +8 -0
  144. package/src/api/subscriptions/schemas/changePlanSchema.ts +9 -0
  145. package/src/api/subscriptions/schemas/createSubscriptionSchema.ts +11 -0
  146. package/src/api/subscriptions/schemas/entitlementsSchema.ts +21 -0
  147. package/src/api/subscriptions/schemas/mrrSchema.ts +13 -0
  148. package/src/api/subscriptions/schemas/planDefinitionSchema.ts +71 -0
  149. package/src/api/subscriptions/schemas/planResourceSchema.ts +25 -0
  150. package/src/api/subscriptions/schemas/subscriptionEventResourceSchema.ts +8 -0
  151. package/src/api/subscriptions/schemas/subscriptionQuerySchema.ts +19 -0
  152. package/src/api/subscriptions/schemas/subscriptionResourceSchema.ts +6 -0
  153. package/src/api/subscriptions/schemas/subscriptionSettingsSchema.ts +32 -0
  154. package/src/api/subscriptions/schemas/subscriptionStatsSchema.ts +23 -0
  155. package/src/api/subscriptions/services/BillingService.ts +437 -0
  156. package/src/api/subscriptions/services/SubscriptionConfig.ts +56 -0
  157. package/src/api/subscriptions/services/SubscriptionService.ts +867 -0
  158. package/src/api/subscriptions/services/UsageService.ts +118 -0
  159. package/src/api/users/__tests__/AdminUserController.spec.ts +80 -1
  160. package/src/api/users/__tests__/CredentialService.spec.ts +177 -0
  161. package/src/api/users/__tests__/EmailVerification.spec.ts +29 -18
  162. package/src/api/users/__tests__/PasswordReset.spec.ts +3 -0
  163. package/src/api/users/__tests__/RegistrationService.spec.ts +148 -1
  164. package/src/api/users/__tests__/SessionService.spec.ts +142 -1
  165. package/src/api/users/atoms/realmAuthSettingsAtom.ts +10 -1
  166. package/src/api/users/controllers/UserController.ts +3 -8
  167. package/src/api/users/notifications/UserNotifications.ts +23 -0
  168. package/src/api/users/schemas/loginSchema.ts +1 -1
  169. package/src/api/users/services/CredentialService.ts +51 -4
  170. package/src/api/users/services/RegistrationService.ts +38 -9
  171. package/src/api/users/services/SessionService.ts +62 -9
  172. package/src/api/users/services/UserService.ts +21 -12
  173. package/src/api/workflows/__tests__/$workflow.spec.ts +616 -0
  174. package/src/api/workflows/controllers/AdminWorkflowController.ts +191 -0
  175. package/src/api/workflows/entities/workflowExecutions.ts +74 -0
  176. package/src/api/workflows/entities/workflowStepExecutions.ts +74 -0
  177. package/src/api/workflows/entities/workflowStepLogs.ts +13 -0
  178. package/src/api/workflows/index.browser.ts +22 -0
  179. package/src/api/workflows/index.ts +124 -0
  180. package/src/api/workflows/jobs/WorkflowJobs.ts +77 -0
  181. package/src/api/workflows/primitives/$workflow.ts +202 -0
  182. package/src/api/workflows/providers/WorkflowProvider.ts +1284 -0
  183. package/src/api/workflows/schemas/workflowActivitySchema.ts +15 -0
  184. package/src/api/workflows/schemas/workflowConfigAtom.ts +51 -0
  185. package/src/api/workflows/schemas/workflowExecutionDetailSchema.ts +18 -0
  186. package/src/api/workflows/schemas/workflowExecutionQuerySchema.ts +26 -0
  187. package/src/api/workflows/schemas/workflowExecutionResourceSchema.ts +30 -0
  188. package/src/api/workflows/schemas/workflowRegistrationSchema.ts +26 -0
  189. package/src/api/workflows/schemas/workflowStatsSchema.ts +16 -0
  190. package/src/api/workflows/schemas/workflowStepExecutionResourceSchema.ts +15 -0
  191. package/src/api/workflows/services/WorkflowService.ts +382 -0
  192. package/src/cli/core/templates/webAppRouterTs.ts +5 -58
  193. package/src/cli/vendor/__tests__/VendorService.spec.ts +283 -178
  194. package/src/cli/vendor/services/VendorService.ts +126 -27
  195. package/src/core/__tests__/TypeProvider.spec.ts +4 -2
  196. package/src/core/providers/SchemaValidator.ts +1 -1
  197. package/src/core/providers/TypeProvider.ts +46 -3
  198. package/src/orm/__tests__/enums.spec.ts +22 -29
  199. package/src/orm/__tests__/orm-showcase-tests.ts +430 -0
  200. package/src/orm/__tests__/orm-showcase.spec.ts +167 -0
  201. package/src/orm/core/providers/DatabaseTypeProvider.ts +0 -29
  202. package/src/orm/postgres/services/PostgresModelBuilder.ts +3 -6
  203. package/src/react/router/__tests__/$page.browser.spec.tsx +157 -0
  204. package/src/react/router/providers/ReactBrowserProvider.ts +39 -0
  205. package/src/react/router/providers/ReactBrowserRouterProvider.ts +22 -0
  206. package/src/security/__tests__/$secure-combinations.spec.ts +945 -0
  207. package/src/security/primitives/$secure.ts +28 -0
  208. package/dist/billing/index.d.ts.map +0 -1
  209. package/dist/billing/index.js.map +0 -1
  210. package/src/billing/__tests__/BillingService.spec.ts +0 -136
  211. /package/src/{billing → api/payments}/entities/paymentMethods.ts +0 -0
  212. /package/src/{billing → api/payments}/entities/refunds.ts +0 -0
  213. /package/src/{billing → api/payments}/schemas/intentSchemas.ts +0 -0
  214. /package/src/{billing → api/payments}/schemas/paymentMethodSchemas.ts +0 -0
  215. /package/src/{billing → api/payments}/schemas/refundSchemas.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/api/invitations/entities/invitations.ts","../../../src/orm/core/schemas/insertSchema.ts","../../../src/orm/core/schemas/updateSchema.ts","../../../src/orm/core/primitives/$entity.ts","../../../src/orm/core/constants/PG_SYMBOLS.ts","../../../src/orm/core/helpers/pgAttr.ts","../../../src/orm/core/schemas/databaseEnvSchema.ts","../../../src/api/invitations/providers/InvitationProvider.ts","../../../src/api/invitations/schemas/createInvitationSchema.ts","../../../src/api/invitations/schemas/invitationQuerySchema.ts","../../../src/api/invitations/schemas/invitationWithResourceInfoSchema.ts","../../../src/api/invitations/schemas/myInvitationsQuerySchema.ts","../../../src/api/invitations/services/InvitationService.ts","../../../src/api/invitations/controllers/AdminInvitationController.ts","../../../src/api/invitations/controllers/InvitationController.ts","../../../src/api/invitations/jobs/InvitationJobs.ts","../../../src/api/invitations/schemas/invitationConfigAtom.ts","../../../src/api/invitations/schemas/invitationResourceSchema.ts","../../../src/api/invitations/index.ts"],"mappings":"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"}
@@ -0,0 +1,665 @@
1
+ import { $atom, $inject, $module, Alepha, t } from "alepha";
2
+ import { $secure } from "alepha/security";
3
+ import { $action, BadRequestError, ForbiddenError, okSchema } from "alepha/server";
4
+ import { $entity, $repository, db, pageQuerySchema } from "alepha/orm";
5
+ import { users } from "alepha/api/users";
6
+ import { CryptoProvider } from "alepha/crypto";
7
+ import { DateTimeProvider } from "alepha/datetime";
8
+ import { $logger } from "alepha/logger";
9
+ import { $job } from "alepha/api/jobs";
10
+ //#region ../../src/api/invitations/schemas/invitationQuerySchema.ts
11
+ const invitationQuerySchema = t.extend(pageQuerySchema, {
12
+ email: t.optional(t.text({ description: "Filter by invited email" })),
13
+ resourceType: t.optional(t.text({ description: "Filter by resource type" })),
14
+ resourceId: t.optional(t.text({ description: "Filter by resource ID" })),
15
+ status: t.optional(t.enum([
16
+ "pending",
17
+ "accepted",
18
+ "declined",
19
+ "expired",
20
+ "revoked"
21
+ ])),
22
+ invitedBy: t.optional(t.uuid())
23
+ });
24
+ //#endregion
25
+ //#region ../../src/api/invitations/entities/invitations.ts
26
+ const invitations = $entity({
27
+ name: "invitations",
28
+ schema: t.object({
29
+ id: db.primaryKey(t.uuid()),
30
+ version: db.version(),
31
+ createdAt: db.createdAt(),
32
+ updatedAt: db.updatedAt(),
33
+ invitedBy: db.ref(t.uuid(), () => users.cols.id, { onDelete: "cascade" }),
34
+ email: t.string({ format: "email" }),
35
+ resourceType: t.text({
36
+ minLength: 1,
37
+ maxLength: 100
38
+ }),
39
+ resourceId: t.text({
40
+ minLength: 1,
41
+ maxLength: 255
42
+ }),
43
+ status: t.enum([
44
+ "pending",
45
+ "accepted",
46
+ "declined",
47
+ "expired",
48
+ "revoked"
49
+ ]),
50
+ roles: t.optional(t.array(t.text())),
51
+ metadata: t.optional(t.record(t.text(), t.any())),
52
+ token: t.text(),
53
+ expiresAt: t.datetime(),
54
+ resolvedAt: t.optional(t.datetime()),
55
+ resolvedBy: t.optional(db.ref(t.uuid(), () => users.cols.id))
56
+ }),
57
+ indexes: [
58
+ { columns: ["email", "status"] },
59
+ { columns: [
60
+ "resourceType",
61
+ "resourceId",
62
+ "email",
63
+ "status"
64
+ ] },
65
+ { columns: ["invitedBy"] },
66
+ { columns: ["expiresAt"] },
67
+ {
68
+ columns: ["token"],
69
+ unique: true
70
+ }
71
+ ]
72
+ });
73
+ //#endregion
74
+ //#region ../../src/api/invitations/schemas/invitationResourceSchema.ts
75
+ const invitationResourceSchema = invitations.schema;
76
+ //#endregion
77
+ //#region ../../src/api/invitations/providers/InvitationProvider.ts
78
+ /**
79
+ * Abstract provider that apps implement to customize invitation behavior
80
+ * per resource type.
81
+ */
82
+ var InvitationProvider = class {};
83
+ //#endregion
84
+ //#region ../../src/api/invitations/schemas/invitationConfigAtom.ts
85
+ const invitationConfigAtom = $atom({
86
+ name: "alepha.api.invitations.config",
87
+ schema: t.object({
88
+ expirationDays: t.integer({
89
+ minimum: 1,
90
+ maximum: 90
91
+ }),
92
+ maxPendingPerResource: t.integer({
93
+ minimum: 1,
94
+ maximum: 500
95
+ }),
96
+ maxPendingPerInviter: t.integer({
97
+ minimum: 1,
98
+ maximum: 1e3
99
+ }),
100
+ purgeDays: t.integer({
101
+ minimum: 0,
102
+ maximum: 365
103
+ })
104
+ }),
105
+ default: {
106
+ expirationDays: 7,
107
+ maxPendingPerResource: 50,
108
+ maxPendingPerInviter: 100,
109
+ purgeDays: 90
110
+ }
111
+ });
112
+ //#endregion
113
+ //#region ../../src/api/invitations/services/InvitationService.ts
114
+ var InvitationService = class {
115
+ alepha = $inject(Alepha);
116
+ log = $logger();
117
+ repo = $repository(invitations);
118
+ users = $repository(users);
119
+ crypto = $inject(CryptoProvider);
120
+ dateTime = $inject(DateTimeProvider);
121
+ provider = $inject(InvitationProvider);
122
+ /**
123
+ * Get an invitation by ID.
124
+ */
125
+ async getById(id) {
126
+ return this.repo.getById(id);
127
+ }
128
+ /**
129
+ * Create a new invitation.
130
+ */
131
+ async create(data, inviter) {
132
+ if (data.email === inviter.email) throw new BadRequestError("Cannot invite yourself");
133
+ await this.provider.validateResource(data.resourceType, data.resourceId, inviter);
134
+ const existingUser = await this.users.findOne({ where: { email: { eq: data.email } } });
135
+ if (existingUser) {
136
+ if (await this.provider.isMember(data.resourceType, data.resourceId, data.email, existingUser.id)) throw new BadRequestError("User is already a member of this resource");
137
+ }
138
+ if (await this.repo.findOne({ where: {
139
+ resourceType: { eq: data.resourceType },
140
+ resourceId: { eq: data.resourceId },
141
+ email: { eq: data.email },
142
+ status: { eq: "pending" }
143
+ } })) throw new BadRequestError("A pending invitation already exists for this email and resource");
144
+ const config = this.alepha.store.get(invitationConfigAtom);
145
+ if (await this.repo.count({
146
+ resourceType: { eq: data.resourceType },
147
+ resourceId: { eq: data.resourceId },
148
+ status: { eq: "pending" }
149
+ }) >= config.maxPendingPerResource) throw new BadRequestError(`Maximum pending invitations per resource reached (${config.maxPendingPerResource})`);
150
+ if (await this.repo.count({
151
+ invitedBy: { eq: inviter.id },
152
+ status: { eq: "pending" }
153
+ }) >= config.maxPendingPerInviter) throw new BadRequestError(`Maximum pending invitations per inviter reached (${config.maxPendingPerInviter})`);
154
+ const token = this.crypto.randomUUID();
155
+ const tokenHash = this.crypto.hash(token, "sha256");
156
+ const expiresAt = this.dateTime.now().add(config.expirationDays, "days").toISOString();
157
+ const entity = await this.repo.create({
158
+ invitedBy: inviter.id,
159
+ email: data.email,
160
+ resourceType: data.resourceType,
161
+ resourceId: data.resourceId,
162
+ status: "pending",
163
+ roles: data.roles,
164
+ metadata: data.metadata,
165
+ token: tokenHash,
166
+ expiresAt
167
+ });
168
+ this.log.info("Invitation created", {
169
+ id: entity.id,
170
+ email: data.email,
171
+ resourceType: data.resourceType,
172
+ resourceId: data.resourceId,
173
+ invitedBy: inviter.id
174
+ });
175
+ await this.alepha.events.emit("invitation:created", {
176
+ invitation: entity,
177
+ token,
178
+ inviter
179
+ });
180
+ return entity;
181
+ }
182
+ /**
183
+ * Accept a pending invitation.
184
+ */
185
+ async accept(invitationId, acceptedBy) {
186
+ const invitation = await this.repo.getById(invitationId);
187
+ if (invitation.status !== "pending") throw new BadRequestError(`Invitation is not pending (current status: ${invitation.status})`);
188
+ if (invitation.email !== acceptedBy.email) throw new ForbiddenError("This invitation was sent to a different email");
189
+ const now = this.dateTime.now();
190
+ if (now.isAfter(invitation.expiresAt)) {
191
+ await this.repo.updateById(invitationId, {
192
+ status: "expired",
193
+ resolvedAt: now.toISOString()
194
+ });
195
+ throw new BadRequestError("Invitation has expired");
196
+ }
197
+ if (await this.provider.isMember(invitation.resourceType, invitation.resourceId, invitation.email, acceptedBy.id)) {
198
+ await this.repo.updateById(invitationId, {
199
+ status: "accepted",
200
+ resolvedAt: now.toISOString(),
201
+ resolvedBy: acceptedBy.id
202
+ });
203
+ this.log.info("Invitation accepted (already member)", {
204
+ id: invitationId,
205
+ acceptedBy: acceptedBy.id
206
+ });
207
+ return;
208
+ }
209
+ await this.provider.onAccept(invitation, acceptedBy);
210
+ await this.repo.updateById(invitationId, {
211
+ status: "accepted",
212
+ resolvedAt: now.toISOString(),
213
+ resolvedBy: acceptedBy.id
214
+ });
215
+ this.log.info("Invitation accepted", {
216
+ id: invitationId,
217
+ email: invitation.email,
218
+ resourceType: invitation.resourceType,
219
+ resourceId: invitation.resourceId,
220
+ acceptedBy: acceptedBy.id
221
+ });
222
+ await this.alepha.events.emit("invitation:accepted", {
223
+ invitation,
224
+ acceptedBy
225
+ });
226
+ }
227
+ /**
228
+ * Decline a pending invitation.
229
+ */
230
+ async decline(invitationId, declinedBy) {
231
+ const invitation = await this.repo.getById(invitationId);
232
+ if (invitation.status !== "pending") throw new BadRequestError(`Invitation is not pending (current status: ${invitation.status})`);
233
+ if (invitation.email !== declinedBy.email) throw new ForbiddenError("This invitation was sent to a different email");
234
+ const now = this.dateTime.now();
235
+ await this.repo.updateById(invitationId, {
236
+ status: "declined",
237
+ resolvedAt: now.toISOString(),
238
+ resolvedBy: declinedBy.id
239
+ });
240
+ this.log.info("Invitation declined", {
241
+ id: invitationId,
242
+ email: invitation.email,
243
+ resourceType: invitation.resourceType,
244
+ resourceId: invitation.resourceId,
245
+ declinedBy: declinedBy.id
246
+ });
247
+ await this.alepha.events.emit("invitation:declined", {
248
+ invitation,
249
+ declinedBy
250
+ });
251
+ }
252
+ /**
253
+ * Revoke a pending invitation (by the inviter or admin).
254
+ */
255
+ async revoke(invitationId, revokedBy) {
256
+ const invitation = await this.repo.getById(invitationId);
257
+ if (invitation.status !== "pending") throw new BadRequestError(`Invitation is not pending (current status: ${invitation.status})`);
258
+ const now = this.dateTime.now();
259
+ await this.repo.updateById(invitationId, {
260
+ status: "revoked",
261
+ resolvedAt: now.toISOString(),
262
+ resolvedBy: revokedBy.id
263
+ });
264
+ this.log.info("Invitation revoked", {
265
+ id: invitationId,
266
+ email: invitation.email,
267
+ resourceType: invitation.resourceType,
268
+ resourceId: invitation.resourceId,
269
+ revokedBy: revokedBy.id
270
+ });
271
+ await this.alepha.events.emit("invitation:revoked", {
272
+ invitation,
273
+ revokedBy
274
+ });
275
+ }
276
+ /**
277
+ * Find invitations for a given email with resource info enrichment.
278
+ */
279
+ async findByEmail(email, query = {}) {
280
+ const where = this.repo.createQueryWhere();
281
+ where.email = { eq: email };
282
+ if (query.status) where.status = { eq: query.status };
283
+ const results = await this.repo.findMany({
284
+ where,
285
+ orderBy: {
286
+ column: "createdAt",
287
+ direction: "desc"
288
+ }
289
+ });
290
+ const inviterIds = [...new Set(results.map((inv) => inv.invitedBy))];
291
+ const inviters = await this.loadInviters(inviterIds);
292
+ const enriched = [];
293
+ for (const inv of results) {
294
+ const inviter = inviters.get(inv.invitedBy);
295
+ let resourceName = inv.resourceType;
296
+ let resourceUrl;
297
+ try {
298
+ const info = await this.provider.getResourceInfo(inv.resourceType, inv.resourceId);
299
+ resourceName = info.name;
300
+ resourceUrl = info.url;
301
+ } catch (error) {
302
+ this.log.warn("Failed to load resource info for invitation", {
303
+ invitationId: inv.id,
304
+ resourceType: inv.resourceType,
305
+ resourceId: inv.resourceId,
306
+ error
307
+ });
308
+ }
309
+ enriched.push({
310
+ id: inv.id,
311
+ email: inv.email,
312
+ resourceType: inv.resourceType,
313
+ resourceId: inv.resourceId,
314
+ resourceName,
315
+ resourceUrl,
316
+ invitedBy: inv.invitedBy,
317
+ inviterName: this.formatInviterName(inviter),
318
+ inviterEmail: inviter?.email,
319
+ roles: inv.roles,
320
+ status: inv.status,
321
+ createdAt: inv.createdAt,
322
+ expiresAt: inv.expiresAt
323
+ });
324
+ }
325
+ return enriched;
326
+ }
327
+ /**
328
+ * Find invitations for a specific resource.
329
+ */
330
+ async findByResource(resourceType, resourceId, status) {
331
+ const where = this.repo.createQueryWhere();
332
+ where.resourceType = { eq: resourceType };
333
+ where.resourceId = { eq: resourceId };
334
+ if (status) where.status = { eq: status };
335
+ return this.repo.findMany({
336
+ where,
337
+ orderBy: {
338
+ column: "createdAt",
339
+ direction: "desc"
340
+ }
341
+ });
342
+ }
343
+ /**
344
+ * Find invitations with pagination and filtering (admin).
345
+ */
346
+ async findInvitations(query = {}) {
347
+ query.sort ??= "-createdAt";
348
+ const where = this.repo.createQueryWhere();
349
+ if (query.email) where.email = { like: `%${query.email}%` };
350
+ if (query.resourceType) where.resourceType = { eq: query.resourceType };
351
+ if (query.resourceId) where.resourceId = { eq: query.resourceId };
352
+ if (query.status) where.status = { eq: query.status };
353
+ if (query.invitedBy) where.invitedBy = { eq: query.invitedBy };
354
+ return this.repo.paginate(query, { where }, { count: true });
355
+ }
356
+ /**
357
+ * Delete an invitation (admin). Only non-pending invitations can be deleted.
358
+ */
359
+ async deleteInvitation(id) {
360
+ if ((await this.repo.getById(id)).status === "pending") throw new BadRequestError("Cannot delete a pending invitation. Revoke it first.");
361
+ await this.repo.deleteById(id);
362
+ this.log.info("Invitation deleted", { id });
363
+ }
364
+ /**
365
+ * Expire all pending invitations that have passed their expiration date.
366
+ * Returns the number of expired invitations.
367
+ */
368
+ async expirePending() {
369
+ const now = this.dateTime.nowISOString();
370
+ const expired = await this.repo.findMany({ where: {
371
+ status: { eq: "pending" },
372
+ expiresAt: { lt: now }
373
+ } });
374
+ if (expired.length === 0) return 0;
375
+ const ids = expired.map((inv) => inv.id);
376
+ await this.repo.updateMany({ id: { inArray: ids } }, {
377
+ status: "expired",
378
+ resolvedAt: now
379
+ });
380
+ for (const inv of expired) await this.alepha.events.emit("invitation:expired", { invitation: inv });
381
+ this.log.info("Expired pending invitations", { count: expired.length });
382
+ return expired.length;
383
+ }
384
+ /**
385
+ * Purge resolved invitations older than the configured purge days.
386
+ * Returns the number of purged invitations.
387
+ */
388
+ async purgeResolved() {
389
+ const config = this.alepha.store.get(invitationConfigAtom);
390
+ if (config.purgeDays === 0) return 0;
391
+ const cutoff = this.dateTime.now().subtract(config.purgeDays, "days").toISOString();
392
+ const ids = await this.repo.deleteMany({
393
+ status: { inArray: [
394
+ "accepted",
395
+ "declined",
396
+ "expired",
397
+ "revoked"
398
+ ] },
399
+ resolvedAt: { lt: cutoff }
400
+ });
401
+ if (ids.length > 0) this.log.info("Purged resolved invitations", { count: ids.length });
402
+ return ids.length;
403
+ }
404
+ /**
405
+ * Load user records for a list of inviter IDs.
406
+ */
407
+ async loadInviters(ids) {
408
+ if (ids.length === 0) return /* @__PURE__ */ new Map();
409
+ const result = await this.users.findMany({ where: { id: { inArray: ids } } });
410
+ return new Map(result.map((user) => [user.id, user]));
411
+ }
412
+ /**
413
+ * Format inviter display name from user entity.
414
+ */
415
+ formatInviterName(user) {
416
+ if (!user) return;
417
+ if (user.firstName && user.lastName) return `${user.firstName} ${user.lastName}`;
418
+ if (user.firstName) return user.firstName;
419
+ return user.username ?? user.email;
420
+ }
421
+ };
422
+ //#endregion
423
+ //#region ../../src/api/invitations/controllers/AdminInvitationController.ts
424
+ var AdminInvitationController = class {
425
+ url = "/invitations";
426
+ group = "admin:invitations";
427
+ invitationService = $inject(InvitationService);
428
+ /**
429
+ * Find invitations with pagination and filtering.
430
+ */
431
+ findInvitations = $action({
432
+ path: this.url,
433
+ group: this.group,
434
+ use: [$secure({ permissions: ["admin:invitation:read"] })],
435
+ description: "Find invitations with pagination and filtering",
436
+ schema: {
437
+ query: invitationQuerySchema,
438
+ response: t.page(invitationResourceSchema)
439
+ },
440
+ handler: ({ query }) => this.invitationService.findInvitations(query)
441
+ });
442
+ /**
443
+ * Get an invitation by ID.
444
+ */
445
+ getInvitation = $action({
446
+ path: `${this.url}/:id`,
447
+ group: this.group,
448
+ use: [$secure({ permissions: ["admin:invitation:read"] })],
449
+ description: "Get an invitation by ID",
450
+ schema: {
451
+ params: t.object({ id: t.uuid() }),
452
+ response: invitationResourceSchema
453
+ },
454
+ handler: ({ params }) => this.invitationService.getById(params.id)
455
+ });
456
+ /**
457
+ * Revoke a pending invitation.
458
+ */
459
+ revokeInvitation = $action({
460
+ method: "POST",
461
+ path: `${this.url}/:id/revoke`,
462
+ group: this.group,
463
+ use: [$secure({ permissions: ["admin:invitation:delete"] })],
464
+ description: "Revoke a pending invitation",
465
+ schema: {
466
+ params: t.object({ id: t.uuid() }),
467
+ response: okSchema
468
+ },
469
+ handler: async ({ params, user }) => {
470
+ await this.invitationService.revoke(params.id, { id: user.id });
471
+ return { ok: true };
472
+ }
473
+ });
474
+ /**
475
+ * Delete an invitation.
476
+ */
477
+ deleteInvitation = $action({
478
+ method: "DELETE",
479
+ path: `${this.url}/:id`,
480
+ group: this.group,
481
+ use: [$secure({ permissions: ["admin:invitation:delete"] })],
482
+ description: "Delete an invitation",
483
+ schema: {
484
+ params: t.object({ id: t.uuid() }),
485
+ response: okSchema
486
+ },
487
+ handler: async ({ params }) => {
488
+ await this.invitationService.deleteInvitation(params.id);
489
+ return {
490
+ ok: true,
491
+ id: params.id
492
+ };
493
+ }
494
+ });
495
+ };
496
+ //#endregion
497
+ //#region ../../src/api/invitations/schemas/createInvitationSchema.ts
498
+ const createInvitationSchema = t.object({
499
+ email: t.string({ format: "email" }),
500
+ resourceType: t.text({
501
+ minLength: 1,
502
+ maxLength: 100
503
+ }),
504
+ resourceId: t.text({
505
+ minLength: 1,
506
+ maxLength: 255
507
+ }),
508
+ roles: t.optional(t.array(t.text())),
509
+ metadata: t.optional(t.record(t.text(), t.any()))
510
+ });
511
+ //#endregion
512
+ //#region ../../src/api/invitations/schemas/invitationWithResourceInfoSchema.ts
513
+ const invitationWithResourceInfoSchema = t.object({
514
+ id: t.uuid(),
515
+ email: t.string({ format: "email" }),
516
+ resourceType: t.text(),
517
+ resourceId: t.text(),
518
+ resourceName: t.text(),
519
+ resourceUrl: t.optional(t.text()),
520
+ invitedBy: t.uuid(),
521
+ inviterName: t.optional(t.text()),
522
+ inviterEmail: t.optional(t.string({ format: "email" })),
523
+ roles: t.optional(t.array(t.text())),
524
+ status: t.enum([
525
+ "pending",
526
+ "accepted",
527
+ "declined",
528
+ "expired",
529
+ "revoked"
530
+ ]),
531
+ createdAt: t.datetime(),
532
+ expiresAt: t.datetime()
533
+ });
534
+ //#endregion
535
+ //#region ../../src/api/invitations/schemas/myInvitationsQuerySchema.ts
536
+ const myInvitationsQuerySchema = t.object({ status: t.optional(t.enum([
537
+ "pending",
538
+ "accepted",
539
+ "declined",
540
+ "expired",
541
+ "revoked"
542
+ ])) });
543
+ //#endregion
544
+ //#region ../../src/api/invitations/controllers/InvitationController.ts
545
+ var InvitationController = class {
546
+ url = "/invitations";
547
+ group = "invitations";
548
+ invitationService = $inject(InvitationService);
549
+ /**
550
+ * Create a new invitation.
551
+ */
552
+ createInvitation = $action({
553
+ method: "POST",
554
+ path: this.url,
555
+ group: this.group,
556
+ use: [$secure({ permissions: ["invitation:create"] })],
557
+ description: "Create a new invitation",
558
+ schema: {
559
+ body: createInvitationSchema,
560
+ response: invitationResourceSchema
561
+ },
562
+ handler: ({ body, user }) => this.invitationService.create(body, user)
563
+ });
564
+ /**
565
+ * List invitations for the current user.
566
+ */
567
+ getMyInvitations = $action({
568
+ path: `${this.url}/mine`,
569
+ group: this.group,
570
+ use: [$secure()],
571
+ description: "List invitations for the current user",
572
+ schema: {
573
+ query: myInvitationsQuerySchema,
574
+ response: t.array(invitationWithResourceInfoSchema)
575
+ },
576
+ handler: ({ query, user }) => this.invitationService.findByEmail(user.email, query)
577
+ });
578
+ /**
579
+ * Accept an invitation.
580
+ */
581
+ acceptInvitation = $action({
582
+ method: "POST",
583
+ path: `${this.url}/:id/accept`,
584
+ group: this.group,
585
+ use: [$secure()],
586
+ description: "Accept an invitation",
587
+ schema: {
588
+ params: t.object({ id: t.uuid() }),
589
+ response: okSchema
590
+ },
591
+ handler: async ({ params, user }) => {
592
+ await this.invitationService.accept(params.id, user);
593
+ return { ok: true };
594
+ }
595
+ });
596
+ /**
597
+ * Decline an invitation.
598
+ */
599
+ declineInvitation = $action({
600
+ method: "POST",
601
+ path: `${this.url}/:id/decline`,
602
+ group: this.group,
603
+ use: [$secure()],
604
+ description: "Decline an invitation",
605
+ schema: {
606
+ params: t.object({ id: t.uuid() }),
607
+ response: okSchema
608
+ },
609
+ handler: async ({ params, user }) => {
610
+ await this.invitationService.decline(params.id, user);
611
+ return { ok: true };
612
+ }
613
+ });
614
+ };
615
+ //#endregion
616
+ //#region ../../src/api/invitations/jobs/InvitationJobs.ts
617
+ var InvitationJobs = class {
618
+ log = $logger();
619
+ invitationService = $inject(InvitationService);
620
+ /**
621
+ * Expire pending invitations that have passed their expiration date.
622
+ */
623
+ expireInvitations = $job({
624
+ cron: "0 * * * *",
625
+ lock: true,
626
+ handler: async () => {
627
+ const count = await this.invitationService.expirePending();
628
+ if (count > 0) this.log.info(`Expired ${count} invitations`);
629
+ }
630
+ });
631
+ /**
632
+ * Purge old resolved invitations.
633
+ */
634
+ purgeInvitations = $job({
635
+ cron: "0 3 * * *",
636
+ lock: true,
637
+ handler: async () => {
638
+ const count = await this.invitationService.purgeResolved();
639
+ if (count > 0) this.log.info(`Purged ${count} old invitations`);
640
+ }
641
+ });
642
+ };
643
+ //#endregion
644
+ //#region ../../src/api/invitations/index.ts
645
+ /**
646
+ * Invitation management module — create, accept, decline, revoke, and expire invitations.
647
+ *
648
+ * @module alepha.api.invitations
649
+ */
650
+ const AlephaApiInvitations = $module({
651
+ name: "alepha.api.invitations",
652
+ services: [
653
+ InvitationService,
654
+ InvitationJobs,
655
+ InvitationController,
656
+ AdminInvitationController
657
+ ],
658
+ register: (alepha) => {
659
+ alepha.with(InvitationService).with(InvitationJobs).with(InvitationController).with(AdminInvitationController);
660
+ }
661
+ });
662
+ //#endregion
663
+ export { AdminInvitationController, AlephaApiInvitations, InvitationController, InvitationJobs, InvitationProvider, InvitationService, createInvitationSchema, invitationConfigAtom, invitationQuerySchema, invitationResourceSchema, invitationWithResourceInfoSchema, invitations, myInvitationsQuerySchema };
664
+
665
+ //# sourceMappingURL=index.js.map