@saasicat/nest 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/_entries.cjs +17678 -0
  2. package/dist/admin/index.cjs +4 -1274
  3. package/dist/admin/index.d.cts +10 -171
  4. package/dist/admin/index.d.ts +10 -171
  5. package/dist/admin/index.js +13 -4
  6. package/dist/admin-resources.module-BZN_yBFj.d.cts +40 -0
  7. package/dist/admin-resources.module-Cms8MY6h.d.ts +40 -0
  8. package/dist/admin-stats.module-15ac5KY3.d.ts +201 -0
  9. package/dist/admin-stats.module-v4SVvWzj.d.cts +201 -0
  10. package/dist/billing/index.cjs +4 -5128
  11. package/dist/billing/index.d.cts +8 -719
  12. package/dist/billing/index.d.ts +8 -719
  13. package/dist/billing/index.js +7 -10
  14. package/dist/catalog/index.cjs +4 -5624
  15. package/dist/catalog/index.d.cts +7 -427
  16. package/dist/catalog/index.d.ts +7 -427
  17. package/dist/catalog/index.js +14 -12
  18. package/dist/catalog.module-BKObceo0.d.ts +103 -0
  19. package/dist/catalog.module-Dw2Hrbyu.d.cts +103 -0
  20. package/dist/checkout-offer/index.cjs +4 -807
  21. package/dist/checkout-offer/index.d.cts +5 -84
  22. package/dist/checkout-offer/index.d.ts +5 -84
  23. package/dist/checkout-offer/index.js +3 -2
  24. package/dist/checkout-offer.module-Y0hDOVrq.d.ts +85 -0
  25. package/dist/checkout-offer.module-ZYF5IsDY.d.cts +85 -0
  26. package/dist/{chunk-5DDCSGZC.js → chunk-33TP26MR.js} +144 -356
  27. package/dist/{chunk-CK54YKVK.js → chunk-75JABGZK.js} +16 -16
  28. package/dist/{chunk-HRU3CP57.js → chunk-BOADBIGB.js} +1 -1
  29. package/dist/{chunk-ZLUGQE5D.js → chunk-E7AJ42AB.js} +8 -8
  30. package/dist/{chunk-6LP7CDS2.js → chunk-F3VV6EXG.js} +18 -13
  31. package/dist/{chunk-PLDHI6NA.js → chunk-FVT7KTUI.js} +258 -3
  32. package/dist/{chunk-RZU4HIAN.js → chunk-GBDUH6DO.js} +26 -23
  33. package/dist/{chunk-K3OPNVFR.js → chunk-HBFU5AN3.js} +5 -9
  34. package/dist/chunk-HWGIMNWR.js +0 -0
  35. package/dist/chunk-IRWZC3GC.js +755 -0
  36. package/dist/chunk-L4KTQ6CL.js +20 -0
  37. package/dist/{chunk-T5SXXAKG.js → chunk-LZHLGUQI.js} +1 -1
  38. package/dist/{chunk-YHHE4KDA.js → chunk-PUXLPUVH.js} +351 -21
  39. package/dist/chunk-TXDH4FUA.js +211 -0
  40. package/dist/chunk-UF53DWWR.js +0 -0
  41. package/dist/{chunk-AJ3EPELS.js → chunk-V34AA7C7.js} +1 -1
  42. package/dist/chunk-WJ6BMDL3.js +313 -0
  43. package/dist/{chunk-M6CZQYPY.js → chunk-Z3FWN3HJ.js} +2 -2
  44. package/dist/discovery/index.cjs +4 -588
  45. package/dist/discovery/index.js +3 -3
  46. package/dist/{enforce-quota.interceptor-cv7r80VM.d.cts → enforce-quota.interceptor-BhkX5nq2.d.cts} +127 -12
  47. package/dist/{enforce-quota.interceptor-Dj1Kusr5.d.ts → enforce-quota.interceptor-CcqZc0Yu.d.ts} +127 -12
  48. package/dist/entitlement/index.cjs +4 -780
  49. package/dist/entitlement/index.d.cts +3 -1
  50. package/dist/entitlement/index.d.ts +3 -1
  51. package/dist/entitlement/index.js +2 -3
  52. package/dist/index.cjs +4 -14975
  53. package/dist/index.d.cts +22 -54
  54. package/dist/index.d.ts +22 -54
  55. package/dist/index.js +88 -369
  56. package/dist/module-CSN8j8Tp.d.cts +39 -0
  57. package/dist/module-DgYJur6f.d.ts +39 -0
  58. package/dist/plan-versions.service-BB36Q1bg.d.ts +329 -0
  59. package/dist/plan-versions.service-CUR2Whyr.d.cts +329 -0
  60. package/dist/platform/index.cjs +4 -2779
  61. package/dist/platform/index.d.cts +50 -8
  62. package/dist/platform/index.d.ts +50 -8
  63. package/dist/platform/index.js +116 -12
  64. package/dist/promo/index.cjs +4 -995
  65. package/dist/promo/index.d.cts +48 -46
  66. package/dist/promo/index.d.ts +48 -46
  67. package/dist/promo/index.js +10 -2
  68. package/dist/rate-limit.guard-dntqAlfZ.d.cts +19 -0
  69. package/dist/rate-limit.guard-dntqAlfZ.d.ts +19 -0
  70. package/dist/registration/index.cjs +4 -1655
  71. package/dist/registration/index.js +1 -1
  72. package/dist/setup.service-BPwJ7My_.d.cts +45 -0
  73. package/dist/setup.service-D2mrdDDB.d.ts +45 -0
  74. package/dist/subscription-bundle-preview.service-BkJXHAeP.d.cts +438 -0
  75. package/dist/subscription-bundle-preview.service-DBbrE_cw.d.ts +438 -0
  76. package/dist/subscription-bundles.module-BQmoozm5.d.ts +291 -0
  77. package/dist/subscription-bundles.module-DCpV-Pb5.d.cts +291 -0
  78. package/dist/subscription-contract/index.cjs +4 -471
  79. package/dist/subscription-contract/index.d.cts +5 -13
  80. package/dist/subscription-contract/index.d.ts +5 -13
  81. package/dist/subscription-contract.module-CG9fPKAr.d.cts +14 -0
  82. package/dist/subscription-contract.module-CVebZzHR.d.ts +14 -0
  83. package/dist/testing/index.cjs +4 -3756
  84. package/dist/testing/index.d.cts +9 -4
  85. package/dist/testing/index.d.ts +9 -4
  86. package/dist/testing/index.js +13 -7
  87. package/package.json +5 -5
  88. package/dist/admin-manifest.config-DyrQNT7M.d.cts +0 -10
  89. package/dist/admin-manifest.config-DyrQNT7M.d.ts +0 -10
  90. package/dist/admin-manifest.service-Cp6uwvmt.d.cts +0 -33
  91. package/dist/admin-manifest.service-UGgzR1x-.d.ts +0 -33
  92. package/dist/chunk-52UTQRD3.js +0 -326
  93. package/dist/chunk-N3WANKSA.js +0 -20
  94. package/dist/chunk-Q53N43LQ.js +0 -13
  95. /package/dist/{chunk-2FR6ZL7R.js → chunk-DBZGV3HC.js} +0 -0
@@ -1,1655 +1,4 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
-
21
- // src/registration/index.ts
22
- var registration_exports = {};
23
- __export(registration_exports, {
24
- ACTIVATION_ORCHESTRATOR_TOKEN: () => ACTIVATION_ORCHESTRATOR_TOKEN,
25
- BaseIpRateLimitGuard: () => BaseIpRateLimitGuard,
26
- ContinueRegistrationDto: () => ContinueRegistrationDto,
27
- CronExpression: () => import_schedule.CronExpression,
28
- PASSWORD_HASHER_TOKEN: () => PASSWORD_HASHER_TOKEN,
29
- PAYMENT_EVENT_LOG_TOKEN: () => PAYMENT_EVENT_LOG_TOKEN,
30
- PAYMENT_PROVIDER_TOKEN: () => PAYMENT_PROVIDER_TOKEN,
31
- PENDING_REGISTRATION_REPOSITORY_TOKEN: () => PENDING_REGISTRATION_REPOSITORY_TOKEN,
32
- PLAN_CATALOG_LOOKUP_TOKEN: () => PLAN_CATALOG_LOOKUP_TOKEN,
33
- PaymentWebhookDto: () => PaymentWebhookDto,
34
- PendingRegistrationService: () => PendingRegistrationService,
35
- PreviewRegistrationPromoDto: () => PreviewRegistrationPromoDto,
36
- REGISTRATION_AUDIT_LOGGER_TOKEN: () => REGISTRATION_AUDIT_LOGGER_TOKEN,
37
- REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN: () => REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN,
38
- REGISTRATION_CONFIG_TOKEN: () => REGISTRATION_CONFIG_TOKEN,
39
- REGISTRATION_OTP_DELIVERY_TOKEN: () => REGISTRATION_OTP_DELIVERY_TOKEN,
40
- REGISTRATION_PROMO_PREVIEW_TOKEN: () => REGISTRATION_PROMO_PREVIEW_TOKEN,
41
- REGISTRATION_RESUME_BASE_URL_TOKEN: () => REGISTRATION_RESUME_BASE_URL_TOKEN,
42
- REGISTRATION_RESUME_DELIVERY_TOKEN: () => REGISTRATION_RESUME_DELIVERY_TOKEN,
43
- REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN: () => REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN,
44
- RegisterStartDto: () => RegisterStartDto,
45
- RegistrationCleanupCron: () => RegistrationCleanupCron,
46
- RegistrationModule: () => RegistrationModule,
47
- ResendRegistrationOtpDto: () => ResendRegistrationOtpDto,
48
- SLUG_AVAILABILITY_CHECK_TOKEN: () => SLUG_AVAILABILITY_CHECK_TOKEN,
49
- SaveRegistrationConfigDto: () => SaveRegistrationConfigDto,
50
- SaveRegistrationConfigSelectionDto: () => SaveRegistrationConfigSelectionDto,
51
- SelectRegistrationPlanDto: () => SelectRegistrationPlanDto,
52
- StartRegistrationCheckoutDto: () => StartRegistrationCheckoutDto,
53
- USER_ACCOUNT_LOOKUP_TOKEN: () => USER_ACCOUNT_LOOKUP_TOKEN,
54
- VerifyRegistrationOtpDto: () => VerifyRegistrationOtpDto,
55
- computeBreakdown: () => computeBreakdown,
56
- generateOtpCode: () => generateOtpCode,
57
- hashOtpCode: () => hashOtpCode,
58
- resolveModel: () => resolveModel,
59
- slugify: () => slugify,
60
- verifyOtpCode: () => verifyOtpCode
61
- });
62
- module.exports = __toCommonJS(registration_exports);
63
-
64
- // src/registration/helpers.ts
65
- var import_node_crypto = require("crypto");
66
- function generateOtpCode() {
67
- return String((0, import_node_crypto.randomInt)(1e5, 1e6));
68
- }
69
- __name(generateOtpCode, "generateOtpCode");
70
- function hashOtpCode(code) {
71
- return (0, import_node_crypto.createHash)("sha256").update(code).digest("hex");
72
- }
73
- __name(hashOtpCode, "hashOtpCode");
74
- function verifyOtpCode(expectedHash, code) {
75
- const actual = hashOtpCode(code);
76
- if (actual.length !== expectedHash.length) {
77
- return false;
78
- }
79
- try {
80
- return (0, import_node_crypto.timingSafeEqual)(Buffer.from(actual, "hex"), Buffer.from(expectedHash, "hex"));
81
- } catch {
82
- return false;
83
- }
84
- }
85
- __name(verifyOtpCode, "verifyOtpCode");
86
- function slugify(name) {
87
- const transliterated = name.toLowerCase().replace(/ß/g, "ss").replace(/ä/g, "ae").replace(/ö/g, "oe").replace(/ü/g, "ue").normalize("NFKD").replace(/[̀-ͯ]/g, "");
88
- const slug = transliterated.replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
89
- return slug || "verein";
90
- }
91
- __name(slugify, "slugify");
92
-
93
- // src/registration/tokens.ts
94
- var PENDING_REGISTRATION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol("PENDING_REGISTRATION_REPOSITORY");
95
- var REGISTRATION_OTP_DELIVERY_TOKEN = /* @__PURE__ */ Symbol("REGISTRATION_OTP_DELIVERY");
96
- var USER_ACCOUNT_LOOKUP_TOKEN = /* @__PURE__ */ Symbol("USER_ACCOUNT_LOOKUP");
97
- var SLUG_AVAILABILITY_CHECK_TOKEN = /* @__PURE__ */ Symbol("SLUG_AVAILABILITY_CHECK");
98
- var PASSWORD_HASHER_TOKEN = /* @__PURE__ */ Symbol("PASSWORD_HASHER");
99
- var PLAN_CATALOG_LOOKUP_TOKEN = /* @__PURE__ */ Symbol("PLAN_CATALOG_LOOKUP");
100
- var PAYMENT_PROVIDER_TOKEN = /* @__PURE__ */ Symbol("PAYMENT_PROVIDER");
101
- var PAYMENT_EVENT_LOG_TOKEN = /* @__PURE__ */ Symbol("PAYMENT_EVENT_LOG");
102
- var ACTIVATION_ORCHESTRATOR_TOKEN = /* @__PURE__ */ Symbol("ACTIVATION_ORCHESTRATOR");
103
- var REGISTRATION_AUDIT_LOGGER_TOKEN = /* @__PURE__ */ Symbol("REGISTRATION_AUDIT_LOGGER");
104
- var REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN = /* @__PURE__ */ Symbol("REGISTRATION_RESUME_TOKEN_SIGNER");
105
- var REGISTRATION_RESUME_DELIVERY_TOKEN = /* @__PURE__ */ Symbol("REGISTRATION_RESUME_DELIVERY");
106
- var REGISTRATION_RESUME_BASE_URL_TOKEN = /* @__PURE__ */ Symbol("REGISTRATION_RESUME_BASE_URL");
107
- var REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN = /* @__PURE__ */ Symbol("REGISTRATION_CONFIGURATOR_LOOKUP");
108
- var REGISTRATION_PROMO_PREVIEW_TOKEN = /* @__PURE__ */ Symbol("REGISTRATION_PROMO_PREVIEW");
109
- var REGISTRATION_CONFIG_TOKEN = /* @__PURE__ */ Symbol("REGISTRATION_CONFIG");
110
-
111
- // src/registration/pending-registration.service.ts
112
- var import_common = require("@nestjs/common");
113
- var import_types = require("@saasicat/types");
114
- var import_types2 = require("@saasicat/types");
115
-
116
- // src/registration/pricing.ts
117
- function round2(value) {
118
- return Math.round(value * 100) / 100;
119
- }
120
- __name(round2, "round2");
121
- function computeBreakdown(catalog, selection, promo) {
122
- const model = catalog.models.find((m) => m.id === selection.modelId);
123
- if (!model) {
124
- throw new Error(`Unknown model: ${selection.modelId}`);
125
- }
126
- const modelMonthlyNet = round2(model.monthlyNet);
127
- const effectiveQuotas = {
128
- ...model.quotaBase
129
- };
130
- const subtotalMonthlyNet = modelMonthlyNet;
131
- const factor = selection.billingCycle === "YEARLY" ? catalog.cycleDiscount : 1;
132
- const subtotalNet = round2(subtotalMonthlyNet * factor);
133
- const discountAmount = promo ? Math.min(round2(promo.discountAmount), subtotalNet) : 0;
134
- const totalNet = Math.max(0, round2(subtotalNet - discountAmount));
135
- const totalGross = round2(totalNet * (1 + catalog.vatRate / 100));
136
- const yearlySavings = selection.billingCycle === "YEARLY" ? round2(subtotalMonthlyNet * 12 - subtotalMonthlyNet * catalog.cycleDiscount) : 0;
137
- return {
138
- cycle: selection.billingCycle,
139
- effectiveQuotas,
140
- modelMonthlyNet,
141
- subtotalMonthlyNet,
142
- subtotalNet,
143
- discountAmount,
144
- totalNet,
145
- vatRate: catalog.vatRate,
146
- totalGross,
147
- yearlySavings,
148
- appliedPromo: promo ? {
149
- code: "",
150
- label: promo.label,
151
- percent: promo.percent
152
- } : void 0
153
- };
154
- }
155
- __name(computeBreakdown, "computeBreakdown");
156
- function resolveModel(catalog, modelId) {
157
- const model = catalog.models.find((m) => m.id === modelId);
158
- if (!model) throw new Error(`Unknown model: ${modelId}`);
159
- return {
160
- planId: model.planId,
161
- monthlyNet: model.monthlyNet,
162
- yearlyNet: model.yearlyNet
163
- };
164
- }
165
- __name(resolveModel, "resolveModel");
166
-
167
- // src/registration/pending-registration.service.ts
168
- function _ts_decorate(decorators, target, key, desc) {
169
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
170
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
171
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
172
- return c > 3 && r && Object.defineProperty(target, key, r), r;
173
- }
174
- __name(_ts_decorate, "_ts_decorate");
175
- function _ts_metadata(k, v) {
176
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
177
- }
178
- __name(_ts_metadata, "_ts_metadata");
179
- function _ts_param(paramIndex, decorator) {
180
- return function(target, key) {
181
- decorator(target, key, paramIndex);
182
- };
183
- }
184
- __name(_ts_param, "_ts_param");
185
- var PendingRegistrationService = class _PendingRegistrationService {
186
- static {
187
- __name(this, "PendingRegistrationService");
188
- }
189
- repo;
190
- otpDelivery;
191
- userLookup;
192
- slugCheck;
193
- passwordHasher;
194
- planCatalog;
195
- paymentProvider;
196
- paymentEventLog;
197
- activationOrchestrator;
198
- audit;
199
- resumeTokenSigner;
200
- resumeDelivery;
201
- resumeBaseUrl;
202
- configuratorLookup;
203
- promoPreview;
204
- logger = new import_common.Logger(_PendingRegistrationService.name);
205
- constructor(repo, otpDelivery, userLookup, slugCheck, passwordHasher, planCatalog, paymentProvider, paymentEventLog, activationOrchestrator, audit, resumeTokenSigner, resumeDelivery, resumeBaseUrl, configuratorLookup, promoPreview) {
206
- this.repo = repo;
207
- this.otpDelivery = otpDelivery;
208
- this.userLookup = userLookup;
209
- this.slugCheck = slugCheck;
210
- this.passwordHasher = passwordHasher;
211
- this.planCatalog = planCatalog;
212
- this.paymentProvider = paymentProvider;
213
- this.paymentEventLog = paymentEventLog;
214
- this.activationOrchestrator = activationOrchestrator;
215
- this.audit = audit;
216
- this.resumeTokenSigner = resumeTokenSigner;
217
- this.resumeDelivery = resumeDelivery;
218
- this.resumeBaseUrl = resumeBaseUrl;
219
- this.configuratorLookup = configuratorLookup;
220
- this.promoPreview = promoPreview;
221
- }
222
- async record(eventType, pendingRegistrationId, context, metadata) {
223
- try {
224
- await this.audit.log({
225
- eventType,
226
- pendingRegistrationId,
227
- context,
228
- metadata
229
- });
230
- } catch (error) {
231
- const message = error instanceof Error ? error.message : String(error);
232
- this.logger.warn(`Audit-Log fehlgeschlagen (${eventType}): ${message}`);
233
- }
234
- }
235
- /** Public signup plan list for step 3 (frontend `usePublicPlans()`). */
236
- async listPublicPlans() {
237
- return this.planCatalog.listPublicSignupPlans();
238
- }
239
- async selectPlan(input, context) {
240
- const pending = await this.repo.findById(input.pendingRegistrationId);
241
- if (!pending) {
242
- throw new import_common.NotFoundException({
243
- code: "PENDING_REGISTRATION_NOT_FOUND"
244
- });
245
- }
246
- if (pending.expiresAt.getTime() < Date.now()) {
247
- throw new import_common.BadRequestException({
248
- code: "PENDING_REGISTRATION_EXPIRED"
249
- });
250
- }
251
- if (pending.status !== "EMAIL_VERIFIED" && pending.status !== "PLAN_SELECTED" && pending.status !== "CHECKOUT_STARTED") {
252
- throw new import_common.BadRequestException({
253
- code: "INVALID_REGISTRATION_STATE"
254
- });
255
- }
256
- const plan = await this.planCatalog.findPublicSignupPlan(input.planId);
257
- if (!plan) {
258
- throw new import_common.BadRequestException({
259
- code: "PLAN_NOT_AVAILABLE"
260
- });
261
- }
262
- const now = /* @__PURE__ */ new Date();
263
- const expiresAt = new Date(now.getTime() + import_types2.PENDING_ONBOARDING_TTL_DAYS * 24 * 60 * 60 * 1e3);
264
- const updated = await this.repo.update(pending.id, {
265
- status: "PLAN_SELECTED",
266
- currentStep: 4,
267
- selectedPlanId: plan.id,
268
- expiresAt
269
- });
270
- await this.record("PLAN_SELECTED", updated.id, context, {
271
- planId: plan.id
272
- });
273
- return {
274
- pendingRegistrationId: updated.id,
275
- status: updated.status,
276
- nextStep: import_types2.REGISTRATION_STEP_BY_STATUS[updated.status],
277
- selectedPlanId: updated.selectedPlanId ?? plan.id
278
- };
279
- }
280
- async startCheckout(input, context) {
281
- const pending = await this.repo.findById(input.pendingRegistrationId);
282
- if (!pending) {
283
- throw new import_common.NotFoundException({
284
- code: "PENDING_REGISTRATION_NOT_FOUND"
285
- });
286
- }
287
- if (pending.expiresAt.getTime() < Date.now()) {
288
- throw new import_common.BadRequestException({
289
- code: "PENDING_REGISTRATION_EXPIRED"
290
- });
291
- }
292
- if (pending.status !== "PLAN_SELECTED" && pending.status !== "CHECKOUT_STARTED") {
293
- throw new import_common.BadRequestException({
294
- code: "PLAN_NOT_SELECTED"
295
- });
296
- }
297
- if (!pending.selectedPlanId) {
298
- throw new import_common.BadRequestException({
299
- code: "PLAN_NOT_SELECTED"
300
- });
301
- }
302
- const plan = await this.planCatalog.findPublicSignupPlan(pending.selectedPlanId);
303
- if (!plan) {
304
- throw new import_common.BadRequestException({
305
- code: "PLAN_NOT_AVAILABLE"
306
- });
307
- }
308
- const session = await this.paymentProvider.createCheckoutSession({
309
- pendingRegistrationId: pending.id,
310
- planId: pending.selectedPlanId,
311
- email: pending.email,
312
- successUrl: input.successUrl,
313
- cancelUrl: input.cancelUrl
314
- });
315
- const now = /* @__PURE__ */ new Date();
316
- const expiresAt = new Date(now.getTime() + import_types2.PENDING_CHECKOUT_TTL_DAYS * 24 * 60 * 60 * 1e3);
317
- const updated = await this.repo.update(pending.id, {
318
- status: "CHECKOUT_STARTED",
319
- currentStep: 4,
320
- checkoutSessionId: session.sessionId,
321
- checkoutStartedAt: now,
322
- expiresAt
323
- });
324
- await this.record("CHECKOUT_STARTED", updated.id, context, {
325
- sessionId: session.sessionId,
326
- provider: session.provider
327
- });
328
- return {
329
- pendingRegistrationId: updated.id,
330
- status: updated.status,
331
- nextStep: import_types2.REGISTRATION_STEP_BY_STATUS[updated.status],
332
- checkoutSessionId: session.sessionId,
333
- checkoutUrl: session.checkoutUrl
334
- };
335
- }
336
- /**
337
- * Processes a payment webhook idempotently:
338
- * 1. `tryClaim` pins the event ID via a @unique INSERT. Duplicates are
339
- * dropped silently (`ALREADY_PROCESSED`).
340
- * 2. On status `SUCCEEDED` the PendingRegistration is resolved from the
341
- * checkout session and the ActivationOrchestrator triggers the final
342
- * user+tenant+subscription creation in a single transaction.
343
- * 3. After activation the PendingRegistration is deleted.
344
- *
345
- * On errors in step 2/3 the EventLog entry remains — provider retries then
346
- * run into ALREADY_PROCESSED. Operational repair is done manually (status
347
- * inspection + cleanup).
348
- */
349
- async handlePaymentEvent(input, context) {
350
- const claimed = await this.paymentEventLog.tryClaim(input.eventId, {
351
- provider: input.provider,
352
- sessionId: input.sessionId,
353
- status: input.status,
354
- rawPayload: input.rawPayload
355
- });
356
- if (!claimed) {
357
- this.logger.warn(`Idempotenz: PaymentEvent ${input.eventId} bereits verarbeitet \u2014 Duplikat verworfen.`);
358
- await this.record("PAYMENT_DUPLICATE_IGNORED", null, context, {
359
- eventId: input.eventId,
360
- sessionId: input.sessionId
361
- });
362
- return {
363
- activated: false,
364
- reason: "ALREADY_PROCESSED"
365
- };
366
- }
367
- if (input.status !== "SUCCEEDED") {
368
- await this.record("PAYMENT_FAILED", null, context, {
369
- eventId: input.eventId,
370
- sessionId: input.sessionId
371
- });
372
- return {
373
- activated: false,
374
- reason: "PAYMENT_NOT_SUCCEEDED"
375
- };
376
- }
377
- if (!input.sessionId) {
378
- return {
379
- activated: false,
380
- reason: "MISSING_SESSION_ID"
381
- };
382
- }
383
- const pending = await this.repo.findByCheckoutSession(input.sessionId);
384
- if (!pending) {
385
- return {
386
- activated: false,
387
- reason: "PENDING_REGISTRATION_NOT_FOUND"
388
- };
389
- }
390
- if (pending.status !== "CHECKOUT_STARTED" && pending.status !== "PLAN_SELECTED") {
391
- return {
392
- activated: false,
393
- reason: "INVALID_STATE"
394
- };
395
- }
396
- await this.record("PAYMENT_RECEIVED", pending.id, context, {
397
- eventId: input.eventId,
398
- sessionId: input.sessionId
399
- });
400
- const result = await this.activationOrchestrator.activate(pending);
401
- await this.repo.delete(pending.id);
402
- await this.record("ACTIVATION_COMPLETED", pending.id, context, {
403
- userId: result.userId,
404
- tenantId: result.tenantId,
405
- subscriptionId: result.subscriptionId
406
- });
407
- this.logger.log(`Aktivierung erfolgreich: pending=${pending.id} \u2192 user=${result.userId} tenant=${result.tenantId} subscription=${result.subscriptionId}`);
408
- return {
409
- activated: true,
410
- result
411
- };
412
- }
413
- /**
414
- * Deletes all PendingRegistration records with `expiresAt < now`.
415
- * Full deletion (no anonymization path) is the simpler option: the schema
416
- * holds `email`, `firstName`, `lastName`, `passwordHash` as NOT NULL, and
417
- * the unique email is exactly what needs to become free again after expiry.
418
- *
419
- * The batch `limit` guards against memory spikes on large backlogs — the
420
- * caller (cron) keeps calling until `moreAvailable === false`.
421
- */
422
- async runCleanup(now, limit = 500) {
423
- if (limit <= 0) {
424
- return {
425
- deleted: 0,
426
- moreAvailable: false
427
- };
428
- }
429
- const expired = await this.repo.findExpired(now, limit);
430
- for (const pending of expired) {
431
- try {
432
- await this.repo.delete(pending.id);
433
- } catch (error) {
434
- const message = error instanceof Error ? error.message : String(error);
435
- this.logger.warn(`Cleanup: PendingRegistration ${pending.id} konnte nicht geloescht werden (${message}).`);
436
- }
437
- }
438
- if (expired.length > 0) {
439
- this.logger.log(`Cleanup: ${expired.length} abgelaufene PendingRegistrations geloescht.`);
440
- }
441
- return {
442
- deleted: expired.length,
443
- moreAvailable: expired.length >= limit
444
- };
445
- }
446
- async start(input, context) {
447
- const email = normalizeEmail(input.email);
448
- if (await this.userLookup.hasActiveUser(email)) {
449
- this.logger.log(`register/start fuer aktiven Account ignoriert (${email}).`);
450
- await this.record("REGISTRATION_NEUTRAL_ACTIVE_USER", null, context);
451
- return {
452
- neutral: true
453
- };
454
- }
455
- const existing = await this.repo.findByEmail(email);
456
- if (existing) {
457
- if (existing.expiresAt.getTime() < Date.now()) {
458
- await this.repo.delete(existing.id);
459
- await this.record("REGISTRATION_NEUTRAL_EXPIRED", existing.id, context);
460
- } else if (existing.status === "PENDING_EMAIL_VERIFICATION") {
461
- await this.regenerateOtp(existing);
462
- await this.record("REGISTRATION_NEUTRAL_REPLAY", existing.id, context, {
463
- status: existing.status
464
- });
465
- return {
466
- neutral: true
467
- };
468
- } else {
469
- if (this.resumeTokenSigner && this.resumeDelivery) {
470
- await this.sendResumeLink(existing);
471
- } else {
472
- await this.regenerateOtp(existing);
473
- }
474
- await this.record("REGISTRATION_NEUTRAL_REPLAY", existing.id, context, {
475
- status: existing.status
476
- });
477
- return {
478
- neutral: true
479
- };
480
- }
481
- }
482
- const slug = await this.resolveSlug(input.tenantName, input.tenantSlug);
483
- const passwordHash = await this.passwordHasher.hash(input.password);
484
- const code = generateOtpCode();
485
- const otpHash = hashOtpCode(code);
486
- const now = /* @__PURE__ */ new Date();
487
- const otpExpiresAt = new Date(now.getTime() + import_types2.OTP_TTL_MINUTES * 60 * 1e3);
488
- const expiresAt = new Date(now.getTime() + import_types2.PENDING_EMAIL_TTL_HOURS * 60 * 60 * 1e3);
489
- const pending = await this.repo.create({
490
- tenantName: input.tenantName.trim(),
491
- tenantSlug: slug,
492
- salutation: nullable(input.salutation),
493
- firstName: input.firstName.trim(),
494
- lastName: input.lastName.trim(),
495
- email,
496
- passwordHash,
497
- locale: input.locale ?? "de",
498
- otpHash,
499
- otpExpiresAt,
500
- expiresAt
501
- });
502
- await this.deliverOtp(pending, code);
503
- await this.record("REGISTRATION_STARTED", pending.id, context);
504
- return {
505
- neutral: true
506
- };
507
- }
508
- async verifyOtp(emailRaw, code, context) {
509
- const email = normalizeEmail(emailRaw);
510
- const pending = await this.repo.findByEmail(email);
511
- if (!pending) {
512
- await this.record("OTP_VERIFY_FAILED", null, context, {
513
- reason: "unknown_email"
514
- });
515
- throw new import_common.BadRequestException({
516
- code: "OTP_INVALID"
517
- });
518
- }
519
- if (pending.status !== "PENDING_EMAIL_VERIFICATION") {
520
- return {
521
- status: pending.status,
522
- nextStep: import_types2.REGISTRATION_STEP_BY_STATUS[pending.status],
523
- pendingRegistrationId: pending.id
524
- };
525
- }
526
- if (!pending.otpHash || !pending.otpExpiresAt) {
527
- await this.record("OTP_VERIFY_FAILED", pending.id, context, {
528
- reason: "no_otp_set"
529
- });
530
- throw new import_common.BadRequestException({
531
- code: "OTP_INVALID"
532
- });
533
- }
534
- if (pending.otpExpiresAt.getTime() < Date.now()) {
535
- await this.record("OTP_VERIFY_FAILED", pending.id, context, {
536
- reason: "expired"
537
- });
538
- throw new import_common.BadRequestException({
539
- code: "OTP_EXPIRED"
540
- });
541
- }
542
- const maxAttempts = resolveOtpVerifyMaxAttempts();
543
- if (pending.otpAttemptCount >= maxAttempts) {
544
- await this.record("OTP_VERIFY_FAILED", pending.id, context, {
545
- reason: "locked"
546
- });
547
- throw new import_common.BadRequestException({
548
- code: "OTP_LOCKED"
549
- });
550
- }
551
- const attemptCount = await this.repo.incrementOtpAttemptCount(pending.id);
552
- if (attemptCount > maxAttempts) {
553
- await this.record("OTP_VERIFY_FAILED", pending.id, context, {
554
- reason: "locked"
555
- });
556
- throw new import_common.BadRequestException({
557
- code: "OTP_LOCKED"
558
- });
559
- }
560
- if (!verifyOtpCode(pending.otpHash, code)) {
561
- await this.record("OTP_VERIFY_FAILED", pending.id, context, {
562
- reason: "wrong_code"
563
- });
564
- throw new import_common.BadRequestException({
565
- code: "OTP_INVALID"
566
- });
567
- }
568
- const now = /* @__PURE__ */ new Date();
569
- const updated = await this.repo.update(pending.id, {
570
- status: "EMAIL_VERIFIED",
571
- currentStep: 3,
572
- emailVerifiedAt: now,
573
- otpHash: null,
574
- otpExpiresAt: null,
575
- expiresAt: new Date(now.getTime() + import_types2.PENDING_ONBOARDING_TTL_DAYS * 24 * 60 * 60 * 1e3)
576
- });
577
- await this.record("OTP_VERIFIED", updated.id, context);
578
- return {
579
- status: updated.status,
580
- nextStep: import_types2.REGISTRATION_STEP_BY_STATUS[updated.status],
581
- pendingRegistrationId: updated.id
582
- };
583
- }
584
- async resendOtp(emailRaw, context) {
585
- const email = normalizeEmail(emailRaw);
586
- const pending = await this.repo.findByEmail(email);
587
- if (!pending) {
588
- return {
589
- neutral: true
590
- };
591
- }
592
- if (pending.status !== "PENDING_EMAIL_VERIFICATION") {
593
- return {
594
- neutral: true
595
- };
596
- }
597
- await this.regenerateOtp(pending);
598
- await this.record("OTP_RESEND_REQUESTED", pending.id, context);
599
- return {
600
- neutral: true
601
- };
602
- }
603
- async regenerateOtp(pending) {
604
- const now = /* @__PURE__ */ new Date();
605
- const windowMs = import_types2.OTP_RATE_LIMIT_WINDOW_MINUTES * 60 * 1e3;
606
- const withinWindow = pending.lastOtpSentAt !== null && now.getTime() - pending.lastOtpSentAt.getTime() < windowMs;
607
- if (withinWindow && pending.otpSendCount >= import_types2.OTP_RATE_LIMIT_MAX_SENDS) {
608
- this.logger.warn(`OTP-Rate-Limit erreicht fuer ${pending.email} \u2014 Send wird still verworfen.`);
609
- return;
610
- }
611
- const code = generateOtpCode();
612
- const otpHash = hashOtpCode(code);
613
- const otpExpiresAt = new Date(now.getTime() + import_types2.OTP_TTL_MINUTES * 60 * 1e3);
614
- const otpSendCount = withinWindow ? pending.otpSendCount + 1 : 1;
615
- await this.repo.update(pending.id, {
616
- otpHash,
617
- otpExpiresAt,
618
- otpSendCount,
619
- lastOtpSentAt: now,
620
- // New code = fresh attempt budget. Overall throughput stays capped
621
- // by the send rate limit above.
622
- otpAttemptCount: 0
623
- });
624
- await this.deliverOtp(pending, code);
625
- }
626
- async deliverOtp(pending, code) {
627
- try {
628
- await this.otpDelivery.sendVerificationOtp({
629
- to: pending.email,
630
- code,
631
- firstName: pending.firstName,
632
- locale: pending.locale
633
- });
634
- } catch (error) {
635
- const message = error instanceof Error ? error.message : String(error);
636
- this.logger.error(`OTP-Mail an ${pending.email} fehlgeschlagen: ${message}`);
637
- }
638
- }
639
- /**
640
- * Creates a signed resume token (60 min TTL) and sends a magic link to the
641
- * stored email. Mail send errors are logged but not escalated
642
- * (account-enumeration protection).
643
- */
644
- async sendResumeLink(pending) {
645
- if (!this.resumeTokenSigner || !this.resumeDelivery) {
646
- return;
647
- }
648
- const token = await this.resumeTokenSigner.sign({
649
- pendingRegistrationId: pending.id,
650
- ttlMinutes: import_types.REGISTRATION_RESUME_TTL_MINUTES
651
- });
652
- const base = (this.resumeBaseUrl ?? "http://localhost").replace(/\/+$/, "");
653
- const url = `${base}/login?resume=${encodeURIComponent(token)}`;
654
- try {
655
- await this.resumeDelivery.sendResumeEmail({
656
- to: pending.email,
657
- firstName: pending.firstName,
658
- locale: pending.locale,
659
- resumeUrl: url
660
- });
661
- } catch (error) {
662
- const message = error instanceof Error ? error.message : String(error);
663
- this.logger.error(`Resume-Mail an ${pending.email} fehlgeschlagen: ${message}`);
664
- }
665
- }
666
- /**
667
- * Resolves a resume token to the matching onboarding step. Called by the
668
- * frontend from `/register?resume=<jwt>`. On an invalid token the method
669
- * throws `RESUME_TOKEN_INVALID`.
670
- *
671
- * Also returns a public-safe snapshot of the PendingRegistration so the
672
- * frontend can prefill completed steps with the existing data (first name /
673
- * last name, organization name, plan selection ...).
674
- */
675
- async resumeWithToken(input, context) {
676
- if (!this.resumeTokenSigner) {
677
- throw new import_common.BadRequestException({
678
- code: "RESUME_NOT_CONFIGURED"
679
- });
680
- }
681
- let decoded;
682
- try {
683
- decoded = await this.resumeTokenSigner.verify(input.token);
684
- } catch {
685
- throw new import_common.BadRequestException({
686
- code: "RESUME_TOKEN_INVALID"
687
- });
688
- }
689
- const pending = await this.repo.findById(decoded.pendingRegistrationId);
690
- if (!pending) {
691
- throw new import_common.BadRequestException({
692
- code: "RESUME_TOKEN_INVALID"
693
- });
694
- }
695
- if (pending.expiresAt.getTime() < Date.now()) {
696
- throw new import_common.BadRequestException({
697
- code: "PENDING_REGISTRATION_EXPIRED"
698
- });
699
- }
700
- await this.record("REGISTRATION_NEUTRAL_REPLAY", pending.id, context, {
701
- via: "resume_token",
702
- status: pending.status
703
- });
704
- return {
705
- pendingRegistrationId: pending.id,
706
- status: pending.status,
707
- nextStep: import_types2.REGISTRATION_STEP_BY_STATUS[pending.status],
708
- snapshot: toSnapshot(pending)
709
- };
710
- }
711
- /**
712
- * Signs a short-lived resume token for an existing PendingRegistration —
713
- * the login endpoint uses this to send the user into the wizard with
714
- * prefill after successful password verification.
715
- */
716
- async signResumeToken(pendingRegistrationId) {
717
- if (!this.resumeTokenSigner) return null;
718
- return this.resumeTokenSigner.sign({
719
- pendingRegistrationId
720
- });
721
- }
722
- /* ─── Configurator (Step 3) ────────────────────────────────────────── */
723
- /** Returns the (app-specific) configurator catalog. */
724
- async getConfiguratorCatalog() {
725
- if (!this.configuratorLookup) {
726
- throw new import_common.BadRequestException({
727
- code: "CONFIGURATOR_NOT_CONFIGURED"
728
- });
729
- }
730
- return this.configuratorLookup.getCatalog();
731
- }
732
- /**
733
- * Saves the configurator selection (model + cycle + promo) and returns the
734
- * full price breakdown.
735
- *
736
- * Sets:
737
- * - `status = PLAN_SELECTED`
738
- * - `currentStep = 4`
739
- * - `selectedPlanId = <planId from the chosen model>`
740
- * - `configJson` / `billingCycle` / `appliedPromoCode`
741
- * - `expiresAt = now + ONBOARDING_TTL`
742
- */
743
- async saveConfiguration(input, context) {
744
- if (!this.configuratorLookup) {
745
- throw new import_common.BadRequestException({
746
- code: "CONFIGURATOR_NOT_CONFIGURED"
747
- });
748
- }
749
- const pending = await this.repo.findById(input.pendingRegistrationId);
750
- if (!pending) {
751
- throw new import_common.NotFoundException({
752
- code: "PENDING_REGISTRATION_NOT_FOUND"
753
- });
754
- }
755
- if (pending.expiresAt.getTime() < Date.now()) {
756
- throw new import_common.BadRequestException({
757
- code: "PENDING_REGISTRATION_EXPIRED"
758
- });
759
- }
760
- if (pending.status !== "EMAIL_VERIFIED" && pending.status !== "PLAN_SELECTED" && pending.status !== "CHECKOUT_STARTED") {
761
- throw new import_common.BadRequestException({
762
- code: "INVALID_REGISTRATION_STATE"
763
- });
764
- }
765
- const catalog = await this.configuratorLookup.getCatalog();
766
- const model = catalog.models.find((m) => m.id === input.selection.modelId);
767
- if (!model) {
768
- throw new import_common.BadRequestException({
769
- code: "MODEL_NOT_AVAILABLE"
770
- });
771
- }
772
- let promoEval;
773
- if (input.selection.appliedPromoCode && this.promoPreview) {
774
- const dryRun = computeBreakdown(catalog, {
775
- ...input.selection,
776
- appliedPromoCode: null
777
- });
778
- const previewResult = await this.promoPreview.preview({
779
- code: input.selection.appliedPromoCode,
780
- planId: model.planId,
781
- billingCycle: input.selection.billingCycle,
782
- subtotalGross: dryRun.totalGross,
783
- email: pending.email
784
- });
785
- if (previewResult.valid && previewResult.discountAmount && previewResult.percent !== void 0 && previewResult.label) {
786
- promoEval = {
787
- discountAmount: previewResult.discountAmount,
788
- percent: previewResult.percent,
789
- label: previewResult.label
790
- };
791
- }
792
- }
793
- const breakdown = computeBreakdown(catalog, input.selection, promoEval);
794
- if (promoEval) {
795
- breakdown.appliedPromo = {
796
- code: input.selection.appliedPromoCode,
797
- label: promoEval.label,
798
- percent: promoEval.percent
799
- };
800
- }
801
- const now = /* @__PURE__ */ new Date();
802
- const expiresAt = new Date(now.getTime() + import_types2.PENDING_ONBOARDING_TTL_DAYS * 24 * 60 * 60 * 1e3);
803
- const updated = await this.repo.update(pending.id, {
804
- status: "PLAN_SELECTED",
805
- currentStep: 4,
806
- selectedPlanId: model.planId,
807
- configJson: input.selection,
808
- billingCycle: input.selection.billingCycle,
809
- appliedPromoCode: input.selection.appliedPromoCode ?? null,
810
- expiresAt
811
- });
812
- await this.record("PLAN_SELECTED", updated.id, context, {
813
- modelId: model.id,
814
- planId: model.planId,
815
- cycle: input.selection.billingCycle,
816
- hasPromo: !!promoEval
817
- });
818
- return {
819
- pendingRegistrationId: updated.id,
820
- status: updated.status,
821
- nextStep: import_types2.REGISTRATION_STEP_BY_STATUS[updated.status],
822
- selection: input.selection,
823
- breakdown
824
- };
825
- }
826
- /**
827
- * Validates a promo code against the currently stored configuration and
828
- * returns a new breakdown. Does NOT modify the pending — for live preview
829
- * in the frontend. If `null` is passed as `code`, the promo effect is
830
- * removed.
831
- */
832
- async previewConfigPromo(pendingRegistrationId, code) {
833
- if (!this.configuratorLookup) {
834
- throw new import_common.BadRequestException({
835
- code: "CONFIGURATOR_NOT_CONFIGURED"
836
- });
837
- }
838
- const pending = await this.repo.findById(pendingRegistrationId);
839
- if (!pending) {
840
- throw new import_common.NotFoundException({
841
- code: "PENDING_REGISTRATION_NOT_FOUND"
842
- });
843
- }
844
- const config = pending.configJson;
845
- if (!config) {
846
- throw new import_common.BadRequestException({
847
- code: "CONFIG_NOT_SAVED"
848
- });
849
- }
850
- const catalog = await this.configuratorLookup.getCatalog();
851
- const model = catalog.models.find((m) => m.id === config.modelId);
852
- if (!model) {
853
- throw new import_common.BadRequestException({
854
- code: "MODEL_NOT_AVAILABLE"
855
- });
856
- }
857
- let promoEval;
858
- if (code && this.promoPreview) {
859
- const dryRun = computeBreakdown(catalog, {
860
- ...config,
861
- appliedPromoCode: null
862
- });
863
- const previewResult = await this.promoPreview.preview({
864
- code,
865
- planId: model.planId,
866
- billingCycle: config.billingCycle,
867
- subtotalGross: dryRun.totalGross,
868
- email: pending.email
869
- });
870
- if (previewResult.valid && previewResult.discountAmount && previewResult.percent !== void 0 && previewResult.label) {
871
- promoEval = {
872
- discountAmount: previewResult.discountAmount,
873
- percent: previewResult.percent,
874
- label: previewResult.label
875
- };
876
- }
877
- }
878
- const breakdown = computeBreakdown(catalog, config, promoEval);
879
- if (promoEval && code) {
880
- breakdown.appliedPromo = {
881
- code,
882
- label: promoEval.label,
883
- percent: promoEval.percent
884
- };
885
- }
886
- return breakdown;
887
- }
888
- /**
889
- * Helper for step 3 resume: the frontend needs the current breakdown when
890
- * the pending already has a configuration. Pure recomputation against the
891
- * catalog (without promo validation, since promos should be freshly checked
892
- * anyway).
893
- */
894
- async getCurrentBreakdown(pendingRegistrationId) {
895
- if (!this.configuratorLookup) return null;
896
- const pending = await this.repo.findById(pendingRegistrationId);
897
- if (!pending || !pending.configJson) return null;
898
- const catalog = await this.configuratorLookup.getCatalog();
899
- return computeBreakdown(catalog, pending.configJson);
900
- }
901
- async resolveSlug(tenantName, requested) {
902
- const requestedSlug = requested?.trim().toLowerCase() ?? "";
903
- const base = requestedSlug.length > 0 ? requestedSlug : slugify(tenantName);
904
- if (await this.slugCheck.isSlugAvailable(base)) {
905
- return base;
906
- }
907
- for (let i = 2; i < 1e3; i++) {
908
- const candidate = `${base}-${i}`;
909
- if (await this.slugCheck.isSlugAvailable(candidate)) {
910
- return candidate;
911
- }
912
- }
913
- throw new Error(`Konnte keinen freien Slug fuer "${tenantName}" finden.`);
914
- }
915
- };
916
- PendingRegistrationService = _ts_decorate([
917
- (0, import_common.Injectable)(),
918
- _ts_param(0, (0, import_common.Inject)(PENDING_REGISTRATION_REPOSITORY_TOKEN)),
919
- _ts_param(1, (0, import_common.Inject)(REGISTRATION_OTP_DELIVERY_TOKEN)),
920
- _ts_param(2, (0, import_common.Inject)(USER_ACCOUNT_LOOKUP_TOKEN)),
921
- _ts_param(3, (0, import_common.Inject)(SLUG_AVAILABILITY_CHECK_TOKEN)),
922
- _ts_param(4, (0, import_common.Inject)(PASSWORD_HASHER_TOKEN)),
923
- _ts_param(5, (0, import_common.Inject)(PLAN_CATALOG_LOOKUP_TOKEN)),
924
- _ts_param(6, (0, import_common.Inject)(PAYMENT_PROVIDER_TOKEN)),
925
- _ts_param(7, (0, import_common.Inject)(PAYMENT_EVENT_LOG_TOKEN)),
926
- _ts_param(8, (0, import_common.Inject)(ACTIVATION_ORCHESTRATOR_TOKEN)),
927
- _ts_param(9, (0, import_common.Inject)(REGISTRATION_AUDIT_LOGGER_TOKEN)),
928
- _ts_param(10, (0, import_common.Optional)()),
929
- _ts_param(10, (0, import_common.Inject)(REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN)),
930
- _ts_param(11, (0, import_common.Optional)()),
931
- _ts_param(11, (0, import_common.Inject)(REGISTRATION_RESUME_DELIVERY_TOKEN)),
932
- _ts_param(12, (0, import_common.Optional)()),
933
- _ts_param(12, (0, import_common.Inject)(REGISTRATION_RESUME_BASE_URL_TOKEN)),
934
- _ts_param(13, (0, import_common.Optional)()),
935
- _ts_param(13, (0, import_common.Inject)(REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN)),
936
- _ts_param(14, (0, import_common.Optional)()),
937
- _ts_param(14, (0, import_common.Inject)(REGISTRATION_PROMO_PREVIEW_TOKEN)),
938
- _ts_metadata("design:type", Function),
939
- _ts_metadata("design:paramtypes", [
940
- typeof PendingRegistrationRepository === "undefined" ? Object : PendingRegistrationRepository,
941
- typeof RegistrationOtpDelivery === "undefined" ? Object : RegistrationOtpDelivery,
942
- typeof UserAccountLookup === "undefined" ? Object : UserAccountLookup,
943
- typeof SlugAvailabilityCheck === "undefined" ? Object : SlugAvailabilityCheck,
944
- typeof PasswordHasher === "undefined" ? Object : PasswordHasher,
945
- typeof PlanCatalogLookup === "undefined" ? Object : PlanCatalogLookup,
946
- typeof PaymentProvider === "undefined" ? Object : PaymentProvider,
947
- typeof PaymentEventLog === "undefined" ? Object : PaymentEventLog,
948
- typeof ActivationOrchestrator === "undefined" ? Object : ActivationOrchestrator,
949
- typeof RegistrationAuditLogger === "undefined" ? Object : RegistrationAuditLogger,
950
- typeof RegistrationResumeTokenSigner === "undefined" ? Object : RegistrationResumeTokenSigner,
951
- typeof RegistrationResumeDelivery === "undefined" ? Object : RegistrationResumeDelivery,
952
- String,
953
- typeof RegistrationConfiguratorLookup === "undefined" ? Object : RegistrationConfiguratorLookup,
954
- typeof RegistrationPromoPreview === "undefined" ? Object : RegistrationPromoPreview
955
- ])
956
- ], PendingRegistrationService);
957
- function normalizeEmail(value) {
958
- return value.trim().toLowerCase();
959
- }
960
- __name(normalizeEmail, "normalizeEmail");
961
- function resolveOtpVerifyMaxAttempts() {
962
- const raw = process.env.SAAS_PLATFORM_OTP_VERIFY_MAX_ATTEMPTS;
963
- if (!raw) return import_types2.OTP_VERIFY_MAX_ATTEMPTS;
964
- const parsed = Number.parseInt(raw, 10);
965
- return Number.isInteger(parsed) && parsed > 0 ? parsed : import_types2.OTP_VERIFY_MAX_ATTEMPTS;
966
- }
967
- __name(resolveOtpVerifyMaxAttempts, "resolveOtpVerifyMaxAttempts");
968
- function toSnapshot(pending) {
969
- return {
970
- tenantName: pending.tenantName,
971
- tenantSlug: pending.tenantSlug,
972
- salutation: pending.salutation,
973
- firstName: pending.firstName,
974
- lastName: pending.lastName,
975
- email: pending.email,
976
- locale: pending.locale,
977
- status: pending.status,
978
- currentStep: pending.currentStep,
979
- emailVerifiedAt: pending.emailVerifiedAt?.toISOString() ?? null,
980
- selectedPlanId: pending.selectedPlanId,
981
- config: pending.configJson,
982
- billingCycle: pending.billingCycle,
983
- appliedPromoCode: pending.appliedPromoCode,
984
- checkoutSessionId: pending.checkoutSessionId
985
- };
986
- }
987
- __name(toSnapshot, "toSnapshot");
988
- function nullable(value) {
989
- const trimmed = value?.trim();
990
- return trimmed && trimmed.length > 0 ? trimmed : null;
991
- }
992
- __name(nullable, "nullable");
993
-
994
- // src/registration/cleanup.cron.ts
995
- var import_common2 = require("@nestjs/common");
996
- var import_schedule = require("@nestjs/schedule");
997
- function _ts_decorate2(decorators, target, key, desc) {
998
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
999
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1000
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1001
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1002
- }
1003
- __name(_ts_decorate2, "_ts_decorate");
1004
- function _ts_metadata2(k, v) {
1005
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1006
- }
1007
- __name(_ts_metadata2, "_ts_metadata");
1008
- var RegistrationCleanupCron = class _RegistrationCleanupCron {
1009
- static {
1010
- __name(this, "RegistrationCleanupCron");
1011
- }
1012
- service;
1013
- logger = new import_common2.Logger(_RegistrationCleanupCron.name);
1014
- constructor(service) {
1015
- this.service = service;
1016
- }
1017
- async runDaily() {
1018
- await this.runCleanup();
1019
- }
1020
- /**
1021
- * Public API: can be triggered manually from an admin endpoint /
1022
- * `/admin/registration/run-cleanup` (same pattern as
1023
- * `PromoCodeExpirer.run` in the consuming apps).
1024
- */
1025
- async runCleanup(now = /* @__PURE__ */ new Date(), batchSize = 500) {
1026
- let totalDeleted = 0;
1027
- let iterations = 0;
1028
- const MAX_ITERATIONS = 50;
1029
- while (iterations < MAX_ITERATIONS) {
1030
- const result = await this.service.runCleanup(now, batchSize);
1031
- totalDeleted += result.deleted;
1032
- iterations++;
1033
- if (!result.moreAvailable) {
1034
- break;
1035
- }
1036
- }
1037
- if (totalDeleted > 0) {
1038
- this.logger.log(`PendingRegistration-Cleanup abgeschlossen: ${totalDeleted} geloescht in ${iterations} Batches.`);
1039
- }
1040
- }
1041
- };
1042
- _ts_decorate2([
1043
- (0, import_schedule.Cron)("15 4 * * *", {
1044
- timeZone: "Europe/Berlin"
1045
- }),
1046
- _ts_metadata2("design:type", Function),
1047
- _ts_metadata2("design:paramtypes", []),
1048
- _ts_metadata2("design:returntype", Promise)
1049
- ], RegistrationCleanupCron.prototype, "runDaily", null);
1050
- RegistrationCleanupCron = _ts_decorate2([
1051
- (0, import_common2.Injectable)(),
1052
- _ts_metadata2("design:type", Function),
1053
- _ts_metadata2("design:paramtypes", [
1054
- typeof PendingRegistrationService === "undefined" ? Object : PendingRegistrationService
1055
- ])
1056
- ], RegistrationCleanupCron);
1057
-
1058
- // src/registration/ip-rate-limit.guard.ts
1059
- var import_common3 = require("@nestjs/common");
1060
- function _ts_decorate3(decorators, target, key, desc) {
1061
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1062
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1063
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1064
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1065
- }
1066
- __name(_ts_decorate3, "_ts_decorate");
1067
- function _ts_metadata3(k, v) {
1068
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1069
- }
1070
- __name(_ts_metadata3, "_ts_metadata");
1071
- var BaseIpRateLimitGuard = class {
1072
- static {
1073
- __name(this, "BaseIpRateLimitGuard");
1074
- }
1075
- options;
1076
- buckets = /* @__PURE__ */ new Map();
1077
- constructor(options) {
1078
- this.options = options;
1079
- }
1080
- canActivate(context) {
1081
- if (process.env.SAAS_PLATFORM_SKIP_RATE_LIMITS === "1" && process.env.NODE_ENV !== "production") {
1082
- return true;
1083
- }
1084
- const req = context.switchToHttp().getRequest();
1085
- const key = ipFingerprint(req);
1086
- if (this.exceeded(key)) {
1087
- throw new import_common3.HttpException({
1088
- code: "RATE_LIMITED",
1089
- reason: this.options.name,
1090
- retryAfterSeconds: Math.ceil(this.options.windowMs / 1e3)
1091
- }, import_common3.HttpStatus.TOO_MANY_REQUESTS);
1092
- }
1093
- return true;
1094
- }
1095
- exceeded(key) {
1096
- const now = Date.now();
1097
- const bucket = this.buckets.get(key);
1098
- if (!bucket || now - bucket.windowStart > this.options.windowMs) {
1099
- this.buckets.set(key, {
1100
- count: 1,
1101
- windowStart: now
1102
- });
1103
- return false;
1104
- }
1105
- bucket.count += 1;
1106
- return bucket.count > this.options.limit;
1107
- }
1108
- };
1109
- BaseIpRateLimitGuard = _ts_decorate3([
1110
- (0, import_common3.Injectable)(),
1111
- _ts_metadata3("design:type", Function),
1112
- _ts_metadata3("design:paramtypes", [
1113
- Object
1114
- ])
1115
- ], BaseIpRateLimitGuard);
1116
- function ipFingerprint(req) {
1117
- const fwd = req.headers["x-forwarded-for"];
1118
- const first = Array.isArray(fwd) ? fwd[0] : fwd?.split(",")[0]?.trim();
1119
- return first || req.ip || "unknown";
1120
- }
1121
- __name(ipFingerprint, "ipFingerprint");
1122
-
1123
- // src/registration/module.ts
1124
- var import_common4 = require("@nestjs/common");
1125
-
1126
- // src/core/di.ts
1127
- function asProvider(token, impl) {
1128
- if (typeof impl === "object" && impl !== null && "useFactory" in impl && typeof impl.useFactory === "function") {
1129
- const factory = impl;
1130
- return {
1131
- provide: token,
1132
- useFactory: factory.useFactory,
1133
- inject: factory.inject
1134
- };
1135
- }
1136
- return {
1137
- provide: token,
1138
- useValue: impl
1139
- };
1140
- }
1141
- __name(asProvider, "asProvider");
1142
-
1143
- // src/registration/module.ts
1144
- function _ts_decorate4(decorators, target, key, desc) {
1145
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1146
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1147
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1148
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1149
- }
1150
- __name(_ts_decorate4, "_ts_decorate");
1151
- var RegistrationModule = class _RegistrationModule {
1152
- static {
1153
- __name(this, "RegistrationModule");
1154
- }
1155
- static forRoot(options) {
1156
- const providers = [
1157
- ...options.extraProviders ?? [],
1158
- asProvider(PENDING_REGISTRATION_REPOSITORY_TOKEN, options.pendingRegistrationRepository),
1159
- asProvider(REGISTRATION_OTP_DELIVERY_TOKEN, options.otpDelivery),
1160
- asProvider(USER_ACCOUNT_LOOKUP_TOKEN, options.userAccountLookup),
1161
- asProvider(SLUG_AVAILABILITY_CHECK_TOKEN, options.slugAvailabilityCheck),
1162
- asProvider(PASSWORD_HASHER_TOKEN, options.passwordHasher),
1163
- asProvider(PLAN_CATALOG_LOOKUP_TOKEN, options.planCatalogLookup),
1164
- asProvider(PAYMENT_PROVIDER_TOKEN, options.paymentProvider),
1165
- asProvider(PAYMENT_EVENT_LOG_TOKEN, options.paymentEventLog),
1166
- asProvider(ACTIVATION_ORCHESTRATOR_TOKEN, options.activationOrchestrator),
1167
- asProvider(REGISTRATION_AUDIT_LOGGER_TOKEN, options.auditLogger),
1168
- PendingRegistrationService
1169
- ];
1170
- if (options.resumeTokenSigner) {
1171
- providers.push(asProvider(REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN, options.resumeTokenSigner));
1172
- }
1173
- if (options.resumeDelivery) {
1174
- providers.push(asProvider(REGISTRATION_RESUME_DELIVERY_TOKEN, options.resumeDelivery));
1175
- }
1176
- if (options.resumeBaseUrl !== void 0) {
1177
- providers.push({
1178
- provide: REGISTRATION_RESUME_BASE_URL_TOKEN,
1179
- useValue: options.resumeBaseUrl
1180
- });
1181
- }
1182
- if (options.configuratorLookup) {
1183
- providers.push(asProvider(REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN, options.configuratorLookup));
1184
- }
1185
- if (options.promoPreview) {
1186
- providers.push(asProvider(REGISTRATION_PROMO_PREVIEW_TOKEN, options.promoPreview));
1187
- }
1188
- const includeCleanupCron = options.includeCleanupCron ?? true;
1189
- if (includeCleanupCron) {
1190
- providers.push(RegistrationCleanupCron);
1191
- }
1192
- return {
1193
- module: _RegistrationModule,
1194
- global: options.global ?? false,
1195
- imports: options.imports ?? [],
1196
- providers,
1197
- exports: includeCleanupCron ? [
1198
- PendingRegistrationService,
1199
- RegistrationCleanupCron
1200
- ] : [
1201
- PendingRegistrationService
1202
- ]
1203
- };
1204
- }
1205
- };
1206
- RegistrationModule = _ts_decorate4([
1207
- (0, import_common4.Module)({})
1208
- ], RegistrationModule);
1209
-
1210
- // src/registration/dto/register-start.dto.ts
1211
- var import_class_validator = require("class-validator");
1212
- function _ts_decorate5(decorators, target, key, desc) {
1213
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1214
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1215
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1216
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1217
- }
1218
- __name(_ts_decorate5, "_ts_decorate");
1219
- function _ts_metadata4(k, v) {
1220
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1221
- }
1222
- __name(_ts_metadata4, "_ts_metadata");
1223
- var RegisterStartDto = class {
1224
- static {
1225
- __name(this, "RegisterStartDto");
1226
- }
1227
- /** Association/tenant name (required). */
1228
- tenantName;
1229
- /** Optional slug. If left empty, it is generated from `tenantName`. */
1230
- tenantSlug;
1231
- /** Salutation of the administrator (optional). */
1232
- salutation;
1233
- firstName;
1234
- lastName;
1235
- email;
1236
- password;
1237
- /** Terms / privacy / data processing — mandatory acceptance (must be `true`). */
1238
- termsAccepted;
1239
- locale;
1240
- };
1241
- _ts_decorate5([
1242
- (0, import_class_validator.IsString)(),
1243
- (0, import_class_validator.MinLength)(2),
1244
- (0, import_class_validator.MaxLength)(120),
1245
- _ts_metadata4("design:type", String)
1246
- ], RegisterStartDto.prototype, "tenantName", void 0);
1247
- _ts_decorate5([
1248
- (0, import_class_validator.IsOptional)(),
1249
- (0, import_class_validator.IsString)(),
1250
- (0, import_class_validator.Matches)(/^[a-z0-9-]+$/, {
1251
- message: "tenantSlug darf nur Kleinbuchstaben, Ziffern und Bindestriche enthalten."
1252
- }),
1253
- (0, import_class_validator.MaxLength)(60),
1254
- _ts_metadata4("design:type", String)
1255
- ], RegisterStartDto.prototype, "tenantSlug", void 0);
1256
- _ts_decorate5([
1257
- (0, import_class_validator.IsOptional)(),
1258
- (0, import_class_validator.IsString)(),
1259
- (0, import_class_validator.MaxLength)(40),
1260
- _ts_metadata4("design:type", String)
1261
- ], RegisterStartDto.prototype, "salutation", void 0);
1262
- _ts_decorate5([
1263
- (0, import_class_validator.IsString)(),
1264
- (0, import_class_validator.MinLength)(1),
1265
- (0, import_class_validator.MaxLength)(60),
1266
- _ts_metadata4("design:type", String)
1267
- ], RegisterStartDto.prototype, "firstName", void 0);
1268
- _ts_decorate5([
1269
- (0, import_class_validator.IsString)(),
1270
- (0, import_class_validator.MinLength)(1),
1271
- (0, import_class_validator.MaxLength)(60),
1272
- _ts_metadata4("design:type", String)
1273
- ], RegisterStartDto.prototype, "lastName", void 0);
1274
- _ts_decorate5([
1275
- (0, import_class_validator.IsEmail)(),
1276
- (0, import_class_validator.MaxLength)(160),
1277
- _ts_metadata4("design:type", String)
1278
- ], RegisterStartDto.prototype, "email", void 0);
1279
- _ts_decorate5([
1280
- (0, import_class_validator.IsString)(),
1281
- (0, import_class_validator.MinLength)(8),
1282
- (0, import_class_validator.MaxLength)(160),
1283
- _ts_metadata4("design:type", String)
1284
- ], RegisterStartDto.prototype, "password", void 0);
1285
- _ts_decorate5([
1286
- (0, import_class_validator.Equals)(true, {
1287
- message: "AGB, Datenschutzerklaerung und Auftragsverarbeitung muessen zugestimmt werden."
1288
- }),
1289
- _ts_metadata4("design:type", Boolean)
1290
- ], RegisterStartDto.prototype, "termsAccepted", void 0);
1291
- _ts_decorate5([
1292
- (0, import_class_validator.IsOptional)(),
1293
- (0, import_class_validator.IsIn)([
1294
- "de",
1295
- "tr"
1296
- ]),
1297
- _ts_metadata4("design:type", String)
1298
- ], RegisterStartDto.prototype, "locale", void 0);
1299
-
1300
- // src/registration/dto/verify-registration-otp.dto.ts
1301
- var import_class_validator2 = require("class-validator");
1302
- function _ts_decorate6(decorators, target, key, desc) {
1303
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1304
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1305
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1306
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1307
- }
1308
- __name(_ts_decorate6, "_ts_decorate");
1309
- function _ts_metadata5(k, v) {
1310
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1311
- }
1312
- __name(_ts_metadata5, "_ts_metadata");
1313
- var VerifyRegistrationOtpDto = class {
1314
- static {
1315
- __name(this, "VerifyRegistrationOtpDto");
1316
- }
1317
- email;
1318
- otp;
1319
- };
1320
- _ts_decorate6([
1321
- (0, import_class_validator2.IsEmail)(),
1322
- _ts_metadata5("design:type", String)
1323
- ], VerifyRegistrationOtpDto.prototype, "email", void 0);
1324
- _ts_decorate6([
1325
- (0, import_class_validator2.IsString)(),
1326
- (0, import_class_validator2.Matches)(/^\d{6}$/, {
1327
- message: "OTP muss 6 Ziffern sein."
1328
- }),
1329
- _ts_metadata5("design:type", String)
1330
- ], VerifyRegistrationOtpDto.prototype, "otp", void 0);
1331
-
1332
- // src/registration/dto/resend-registration-otp.dto.ts
1333
- var import_class_validator3 = require("class-validator");
1334
- function _ts_decorate7(decorators, target, key, desc) {
1335
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1336
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1337
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1338
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1339
- }
1340
- __name(_ts_decorate7, "_ts_decorate");
1341
- function _ts_metadata6(k, v) {
1342
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1343
- }
1344
- __name(_ts_metadata6, "_ts_metadata");
1345
- var ResendRegistrationOtpDto = class {
1346
- static {
1347
- __name(this, "ResendRegistrationOtpDto");
1348
- }
1349
- email;
1350
- };
1351
- _ts_decorate7([
1352
- (0, import_class_validator3.IsEmail)(),
1353
- _ts_metadata6("design:type", String)
1354
- ], ResendRegistrationOtpDto.prototype, "email", void 0);
1355
-
1356
- // src/registration/dto/select-plan.dto.ts
1357
- var import_class_validator4 = require("class-validator");
1358
- function _ts_decorate8(decorators, target, key, desc) {
1359
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1360
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1361
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1362
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1363
- }
1364
- __name(_ts_decorate8, "_ts_decorate");
1365
- function _ts_metadata7(k, v) {
1366
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1367
- }
1368
- __name(_ts_metadata7, "_ts_metadata");
1369
- var SelectRegistrationPlanDto = class {
1370
- static {
1371
- __name(this, "SelectRegistrationPlanDto");
1372
- }
1373
- pendingRegistrationId;
1374
- planId;
1375
- };
1376
- _ts_decorate8([
1377
- (0, import_class_validator4.IsString)(),
1378
- (0, import_class_validator4.MinLength)(1),
1379
- (0, import_class_validator4.MaxLength)(80),
1380
- _ts_metadata7("design:type", String)
1381
- ], SelectRegistrationPlanDto.prototype, "pendingRegistrationId", void 0);
1382
- _ts_decorate8([
1383
- (0, import_class_validator4.IsString)(),
1384
- (0, import_class_validator4.MinLength)(1),
1385
- (0, import_class_validator4.MaxLength)(40),
1386
- _ts_metadata7("design:type", String)
1387
- ], SelectRegistrationPlanDto.prototype, "planId", void 0);
1388
-
1389
- // src/registration/dto/start-checkout.dto.ts
1390
- var import_class_validator5 = require("class-validator");
1391
- function _ts_decorate9(decorators, target, key, desc) {
1392
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1393
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1394
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1395
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1396
- }
1397
- __name(_ts_decorate9, "_ts_decorate");
1398
- function _ts_metadata8(k, v) {
1399
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1400
- }
1401
- __name(_ts_metadata8, "_ts_metadata");
1402
- var StartRegistrationCheckoutDto = class {
1403
- static {
1404
- __name(this, "StartRegistrationCheckoutDto");
1405
- }
1406
- pendingRegistrationId;
1407
- successUrl;
1408
- cancelUrl;
1409
- };
1410
- _ts_decorate9([
1411
- (0, import_class_validator5.IsString)(),
1412
- (0, import_class_validator5.MinLength)(1),
1413
- (0, import_class_validator5.MaxLength)(80),
1414
- _ts_metadata8("design:type", String)
1415
- ], StartRegistrationCheckoutDto.prototype, "pendingRegistrationId", void 0);
1416
- _ts_decorate9([
1417
- (0, import_class_validator5.IsUrl)({
1418
- require_tld: false
1419
- }),
1420
- (0, import_class_validator5.MaxLength)(500),
1421
- _ts_metadata8("design:type", String)
1422
- ], StartRegistrationCheckoutDto.prototype, "successUrl", void 0);
1423
- _ts_decorate9([
1424
- (0, import_class_validator5.IsUrl)({
1425
- require_tld: false
1426
- }),
1427
- (0, import_class_validator5.MaxLength)(500),
1428
- _ts_metadata8("design:type", String)
1429
- ], StartRegistrationCheckoutDto.prototype, "cancelUrl", void 0);
1430
-
1431
- // src/registration/dto/payment-webhook.dto.ts
1432
- var import_class_validator6 = require("class-validator");
1433
- function _ts_decorate10(decorators, target, key, desc) {
1434
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1435
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1436
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1437
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1438
- }
1439
- __name(_ts_decorate10, "_ts_decorate");
1440
- function _ts_metadata9(k, v) {
1441
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1442
- }
1443
- __name(_ts_metadata9, "_ts_metadata");
1444
- var PaymentWebhookDto = class {
1445
- static {
1446
- __name(this, "PaymentWebhookDto");
1447
- }
1448
- eventId;
1449
- sessionId;
1450
- provider;
1451
- status;
1452
- payload;
1453
- };
1454
- _ts_decorate10([
1455
- (0, import_class_validator6.IsString)(),
1456
- (0, import_class_validator6.MinLength)(1),
1457
- (0, import_class_validator6.MaxLength)(120),
1458
- _ts_metadata9("design:type", String)
1459
- ], PaymentWebhookDto.prototype, "eventId", void 0);
1460
- _ts_decorate10([
1461
- (0, import_class_validator6.IsOptional)(),
1462
- (0, import_class_validator6.IsString)(),
1463
- (0, import_class_validator6.MaxLength)(120),
1464
- _ts_metadata9("design:type", String)
1465
- ], PaymentWebhookDto.prototype, "sessionId", void 0);
1466
- _ts_decorate10([
1467
- (0, import_class_validator6.IsString)(),
1468
- (0, import_class_validator6.MaxLength)(40),
1469
- _ts_metadata9("design:type", String)
1470
- ], PaymentWebhookDto.prototype, "provider", void 0);
1471
- _ts_decorate10([
1472
- (0, import_class_validator6.IsIn)([
1473
- "SUCCEEDED",
1474
- "FAILED"
1475
- ]),
1476
- _ts_metadata9("design:type", String)
1477
- ], PaymentWebhookDto.prototype, "status", void 0);
1478
- _ts_decorate10([
1479
- (0, import_class_validator6.IsOptional)(),
1480
- (0, import_class_validator6.IsObject)(),
1481
- _ts_metadata9("design:type", typeof Record === "undefined" ? Object : Record)
1482
- ], PaymentWebhookDto.prototype, "payload", void 0);
1483
-
1484
- // src/registration/dto/continue-registration.dto.ts
1485
- var import_class_validator7 = require("class-validator");
1486
- function _ts_decorate11(decorators, target, key, desc) {
1487
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1488
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1489
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1490
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1491
- }
1492
- __name(_ts_decorate11, "_ts_decorate");
1493
- function _ts_metadata10(k, v) {
1494
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1495
- }
1496
- __name(_ts_metadata10, "_ts_metadata");
1497
- var ContinueRegistrationDto = class {
1498
- static {
1499
- __name(this, "ContinueRegistrationDto");
1500
- }
1501
- token;
1502
- };
1503
- _ts_decorate11([
1504
- (0, import_class_validator7.IsString)(),
1505
- (0, import_class_validator7.MinLength)(10),
1506
- (0, import_class_validator7.MaxLength)(2e3),
1507
- _ts_metadata10("design:type", String)
1508
- ], ContinueRegistrationDto.prototype, "token", void 0);
1509
-
1510
- // src/registration/dto/save-configuration.dto.ts
1511
- var import_class_validator8 = require("class-validator");
1512
- var import_class_transformer = require("class-transformer");
1513
- function _ts_decorate12(decorators, target, key, desc) {
1514
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1515
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1516
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1517
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1518
- }
1519
- __name(_ts_decorate12, "_ts_decorate");
1520
- function _ts_metadata11(k, v) {
1521
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1522
- }
1523
- __name(_ts_metadata11, "_ts_metadata");
1524
- var SaveRegistrationConfigSelectionDto = class {
1525
- static {
1526
- __name(this, "SaveRegistrationConfigSelectionDto");
1527
- }
1528
- modelId;
1529
- billingCycle;
1530
- appliedPromoCode;
1531
- /**
1532
- * METAMODELL §17a — Bundle consistency. ID of the `CheckoutOffer` that was
1533
- * created on the pricing page (`<app>/register?offer=<id>`). Passed
1534
- * through unchanged in `configJson`; the ActivationOrchestrator freezes it
1535
- * as `packageSnapshot` when the subscription is created and sets the offer
1536
- * to `consumed`. `null` = direct registration without a website offer.
1537
- */
1538
- offerId;
1539
- };
1540
- _ts_decorate12([
1541
- (0, import_class_validator8.IsString)(),
1542
- (0, import_class_validator8.MinLength)(1),
1543
- (0, import_class_validator8.MaxLength)(40),
1544
- _ts_metadata11("design:type", String)
1545
- ], SaveRegistrationConfigSelectionDto.prototype, "modelId", void 0);
1546
- _ts_decorate12([
1547
- (0, import_class_validator8.IsIn)([
1548
- "MONTHLY",
1549
- "YEARLY"
1550
- ]),
1551
- _ts_metadata11("design:type", String)
1552
- ], SaveRegistrationConfigSelectionDto.prototype, "billingCycle", void 0);
1553
- _ts_decorate12([
1554
- (0, import_class_validator8.IsOptional)(),
1555
- (0, import_class_validator8.IsString)(),
1556
- (0, import_class_validator8.MaxLength)(60),
1557
- _ts_metadata11("design:type", Object)
1558
- ], SaveRegistrationConfigSelectionDto.prototype, "appliedPromoCode", void 0);
1559
- _ts_decorate12([
1560
- (0, import_class_validator8.IsOptional)(),
1561
- (0, import_class_validator8.ValidateIf)((_o, value) => value !== null),
1562
- (0, import_class_validator8.IsUUID)(),
1563
- _ts_metadata11("design:type", Object)
1564
- ], SaveRegistrationConfigSelectionDto.prototype, "offerId", void 0);
1565
- var SaveRegistrationConfigDto = class {
1566
- static {
1567
- __name(this, "SaveRegistrationConfigDto");
1568
- }
1569
- pendingRegistrationId;
1570
- selection;
1571
- };
1572
- _ts_decorate12([
1573
- (0, import_class_validator8.IsString)(),
1574
- (0, import_class_validator8.MinLength)(1),
1575
- (0, import_class_validator8.MaxLength)(80),
1576
- _ts_metadata11("design:type", String)
1577
- ], SaveRegistrationConfigDto.prototype, "pendingRegistrationId", void 0);
1578
- _ts_decorate12([
1579
- (0, import_class_validator8.ValidateNested)(),
1580
- (0, import_class_transformer.Type)(() => SaveRegistrationConfigSelectionDto),
1581
- _ts_metadata11("design:type", typeof SaveRegistrationConfigSelectionDto === "undefined" ? Object : SaveRegistrationConfigSelectionDto)
1582
- ], SaveRegistrationConfigDto.prototype, "selection", void 0);
1583
-
1584
- // src/registration/dto/preview-promo.dto.ts
1585
- var import_class_validator9 = require("class-validator");
1586
- function _ts_decorate13(decorators, target, key, desc) {
1587
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1588
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1589
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1590
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1591
- }
1592
- __name(_ts_decorate13, "_ts_decorate");
1593
- function _ts_metadata12(k, v) {
1594
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1595
- }
1596
- __name(_ts_metadata12, "_ts_metadata");
1597
- var PreviewRegistrationPromoDto = class {
1598
- static {
1599
- __name(this, "PreviewRegistrationPromoDto");
1600
- }
1601
- pendingRegistrationId;
1602
- code;
1603
- };
1604
- _ts_decorate13([
1605
- (0, import_class_validator9.IsString)(),
1606
- (0, import_class_validator9.MinLength)(1),
1607
- (0, import_class_validator9.MaxLength)(80),
1608
- _ts_metadata12("design:type", String)
1609
- ], PreviewRegistrationPromoDto.prototype, "pendingRegistrationId", void 0);
1610
- _ts_decorate13([
1611
- (0, import_class_validator9.IsOptional)(),
1612
- (0, import_class_validator9.IsString)(),
1613
- (0, import_class_validator9.MaxLength)(60),
1614
- _ts_metadata12("design:type", String)
1615
- ], PreviewRegistrationPromoDto.prototype, "code", void 0);
1616
- // Annotate the CommonJS export names for ESM import in node:
1617
- 0 && (module.exports = {
1618
- ACTIVATION_ORCHESTRATOR_TOKEN,
1619
- BaseIpRateLimitGuard,
1620
- ContinueRegistrationDto,
1621
- CronExpression,
1622
- PASSWORD_HASHER_TOKEN,
1623
- PAYMENT_EVENT_LOG_TOKEN,
1624
- PAYMENT_PROVIDER_TOKEN,
1625
- PENDING_REGISTRATION_REPOSITORY_TOKEN,
1626
- PLAN_CATALOG_LOOKUP_TOKEN,
1627
- PaymentWebhookDto,
1628
- PendingRegistrationService,
1629
- PreviewRegistrationPromoDto,
1630
- REGISTRATION_AUDIT_LOGGER_TOKEN,
1631
- REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN,
1632
- REGISTRATION_CONFIG_TOKEN,
1633
- REGISTRATION_OTP_DELIVERY_TOKEN,
1634
- REGISTRATION_PROMO_PREVIEW_TOKEN,
1635
- REGISTRATION_RESUME_BASE_URL_TOKEN,
1636
- REGISTRATION_RESUME_DELIVERY_TOKEN,
1637
- REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN,
1638
- RegisterStartDto,
1639
- RegistrationCleanupCron,
1640
- RegistrationModule,
1641
- ResendRegistrationOtpDto,
1642
- SLUG_AVAILABILITY_CHECK_TOKEN,
1643
- SaveRegistrationConfigDto,
1644
- SaveRegistrationConfigSelectionDto,
1645
- SelectRegistrationPlanDto,
1646
- StartRegistrationCheckoutDto,
1647
- USER_ACCOUNT_LOOKUP_TOKEN,
1648
- VerifyRegistrationOtpDto,
1649
- computeBreakdown,
1650
- generateOtpCode,
1651
- hashOtpCode,
1652
- resolveModel,
1653
- slugify,
1654
- verifyOtpCode
1655
- });
1
+ 'use strict';
2
+ // Generated by scripts/build-cjs-stubs.mjs — do not edit.
3
+ // Thin re-export so every entry shares one set of class objects.
4
+ module.exports = require('../_entries.cjs').registrationNs;