@saasicat/nest 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +53 -0
- package/dist/admin/index.cjs +1283 -0
- package/dist/admin/index.d.cts +225 -0
- package/dist/admin/index.d.ts +225 -0
- package/dist/admin/index.js +58 -0
- package/dist/admin-audit.service-9IqXMlZm.d.cts +30 -0
- package/dist/admin-audit.service-9IqXMlZm.d.ts +30 -0
- package/dist/admin-manifest.config-DyrQNT7M.d.cts +10 -0
- package/dist/admin-manifest.config-DyrQNT7M.d.ts +10 -0
- package/dist/aggregation-CJ3qQf92.d.cts +288 -0
- package/dist/aggregation-Dvz9e8X2.d.ts +288 -0
- package/dist/billing/index.cjs +5205 -0
- package/dist/billing/index.d.cts +1326 -0
- package/dist/billing/index.d.ts +1326 -0
- package/dist/billing/index.js +197 -0
- package/dist/catalog/index.cjs +6449 -0
- package/dist/catalog/index.d.cts +1073 -0
- package/dist/catalog/index.d.ts +1073 -0
- package/dist/catalog/index.js +158 -0
- package/dist/checkout-offer/index.cjs +807 -0
- package/dist/checkout-offer/index.d.cts +120 -0
- package/dist/checkout-offer/index.d.ts +120 -0
- package/dist/checkout-offer/index.js +20 -0
- package/dist/chunk-2FR6ZL7R.js +0 -0
- package/dist/chunk-2PNX2QL2.js +347 -0
- package/dist/chunk-2VNZYRDV.js +326 -0
- package/dist/chunk-7MLGHWKO.js +12 -0
- package/dist/chunk-ABB2CRAS.js +31 -0
- package/dist/chunk-AJ3EPELS.js +157 -0
- package/dist/chunk-E56W4U2P.js +90 -0
- package/dist/chunk-HRU3CP57.js +71 -0
- package/dist/chunk-L4SUWH5B.js +14 -0
- package/dist/chunk-M6CZQYPY.js +314 -0
- package/dist/chunk-MDIZUVIK.js +87 -0
- package/dist/chunk-MV6LW5UB.js +217 -0
- package/dist/chunk-NYLON2VC.js +6 -0
- package/dist/chunk-P6MYZMXQ.js +951 -0
- package/dist/chunk-Q53N43LQ.js +13 -0
- package/dist/chunk-QJVPRD3R.js +573 -0
- package/dist/chunk-RIGLQ4BV.js +3367 -0
- package/dist/chunk-SABTXESR.js +24 -0
- package/dist/chunk-SHUYVCID.js +6 -0
- package/dist/chunk-SYEVGPFC.js +686 -0
- package/dist/chunk-V7HUZ6UQ.js +5923 -0
- package/dist/chunk-WPUVJRIN.js +29 -0
- package/dist/chunk-XCZ3TTFK.js +22 -0
- package/dist/chunk-XSGU2Y2O.js +1611 -0
- package/dist/chunk-YNEW3L63.js +190 -0
- package/dist/chunk-YXGHPILG.js +614 -0
- package/dist/chunk-ZL4LLE2Z.js +465 -0
- package/dist/di-CcNeq9v-.d.cts +16 -0
- package/dist/di-CcNeq9v-.d.ts +16 -0
- package/dist/discovery/index.cjs +588 -0
- package/dist/discovery/index.d.cts +299 -0
- package/dist/discovery/index.d.ts +299 -0
- package/dist/discovery/index.js +49 -0
- package/dist/discovery.scanner-CUYLKlYT.d.cts +59 -0
- package/dist/discovery.scanner-CUYLKlYT.d.ts +59 -0
- package/dist/entitlement/index.cjs +805 -0
- package/dist/entitlement/index.d.cts +60 -0
- package/dist/entitlement/index.d.ts +60 -0
- package/dist/entitlement/index.js +57 -0
- package/dist/index.cjs +15918 -0
- package/dist/index.d.cts +85 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.js +956 -0
- package/dist/plan-resolution-CFCoUkrE.d.cts +41 -0
- package/dist/plan-resolution-CFCoUkrE.d.ts +41 -0
- package/dist/platform/index.cjs +2772 -0
- package/dist/platform/index.d.cts +118 -0
- package/dist/platform/index.d.ts +118 -0
- package/dist/platform/index.js +37 -0
- package/dist/promo/index.cjs +995 -0
- package/dist/promo/index.d.cts +121 -0
- package/dist/promo/index.d.ts +121 -0
- package/dist/promo/index.js +58 -0
- package/dist/registration/index.cjs +1687 -0
- package/dist/registration/index.d.cts +444 -0
- package/dist/registration/index.d.ts +444 -0
- package/dist/registration/index.js +82 -0
- package/dist/saas-platform.module-CgZ2omgg.d.cts +180 -0
- package/dist/saas-platform.module-DT9TnCzk.d.ts +180 -0
- package/dist/service-DX8KbGXl.d.cts +109 -0
- package/dist/service-DX8KbGXl.d.ts +109 -0
- package/dist/subscription-contract/index.cjs +471 -0
- package/dist/subscription-contract/index.d.cts +17 -0
- package/dist/subscription-contract/index.d.ts +17 -0
- package/dist/subscription-contract/index.js +21 -0
- package/dist/subscription-contract.service--cm47ZJJ.d.cts +39 -0
- package/dist/subscription-contract.service--cm47ZJJ.d.ts +39 -0
- package/dist/testing/index.cjs +3942 -0
- package/dist/testing/index.d.cts +279 -0
- package/dist/testing/index.d.ts +279 -0
- package/dist/testing/index.js +1195 -0
- package/package.json +185 -0
|
@@ -0,0 +1,1283 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from2, except, desc) => {
|
|
14
|
+
if (from2 && typeof from2 === "object" || typeof from2 === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from2))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from2[key], enumerable: !(desc = __getOwnPropDesc(from2, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/admin/index.ts
|
|
32
|
+
var admin_exports = {};
|
|
33
|
+
__export(admin_exports, {
|
|
34
|
+
ADMIN_MANIFEST_CONFIG: () => ADMIN_MANIFEST_CONFIG,
|
|
35
|
+
ADMIN_STATS_AUDIT_WINDOW_DAYS_TOKEN: () => ADMIN_STATS_AUDIT_WINDOW_DAYS_TOKEN,
|
|
36
|
+
AUDIT_PORT_TOKEN: () => AUDIT_PORT_TOKEN,
|
|
37
|
+
AUDIT_STATS_PORT_TOKEN: () => AUDIT_STATS_PORT_TOKEN,
|
|
38
|
+
AdminAuditService: () => AdminAuditService,
|
|
39
|
+
AdminBypassRlsInterceptor: () => AdminBypassRlsInterceptor,
|
|
40
|
+
AdminManifestModule: () => AdminManifestModule,
|
|
41
|
+
AdminManifestService: () => AdminManifestService,
|
|
42
|
+
AdminModule: () => AdminModule,
|
|
43
|
+
AdminPublicBootController: () => AdminPublicBootController,
|
|
44
|
+
AdminStatsController: () => AdminStatsController,
|
|
45
|
+
AdminStatsModule: () => AdminStatsModule,
|
|
46
|
+
AdminStatsService: () => AdminStatsService,
|
|
47
|
+
MFA_PORT_TOKEN: () => MFA_PORT_TOKEN,
|
|
48
|
+
MfaGuard: () => MfaGuard,
|
|
49
|
+
MfaService: () => MfaService,
|
|
50
|
+
PLATFORM_CORE_CONTRIBUTION_TOKEN: () => PLATFORM_CORE_CONTRIBUTION_TOKEN,
|
|
51
|
+
PLATFORM_CORE_MANIFEST_CONTRIBUTION: () => PLATFORM_CORE_MANIFEST_CONTRIBUTION,
|
|
52
|
+
PROMO_CODE_STATS_PORT_TOKEN: () => PROMO_CODE_STATS_PORT_TOKEN,
|
|
53
|
+
REQUIRE_MFA_KEY: () => REQUIRE_MFA_KEY,
|
|
54
|
+
RLS_BYPASS_PORT_TOKEN: () => RLS_BYPASS_PORT_TOKEN,
|
|
55
|
+
RequireMfa: () => RequireMfa,
|
|
56
|
+
SUBSCRIPTION_STATS_PORT_TOKEN: () => SUBSCRIPTION_STATS_PORT_TOKEN,
|
|
57
|
+
SuperAdminGuard: () => SuperAdminGuard
|
|
58
|
+
});
|
|
59
|
+
module.exports = __toCommonJS(admin_exports);
|
|
60
|
+
|
|
61
|
+
// src/admin/tokens.ts
|
|
62
|
+
var MFA_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/MfaPort");
|
|
63
|
+
var AUDIT_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/AuditPort");
|
|
64
|
+
var RLS_BYPASS_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/RlsBypassPort");
|
|
65
|
+
|
|
66
|
+
// src/admin/super-admin.guard.ts
|
|
67
|
+
var import_common = require("@nestjs/common");
|
|
68
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
69
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
70
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
71
|
+
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;
|
|
72
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
73
|
+
}
|
|
74
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
75
|
+
var SuperAdminGuard = class {
|
|
76
|
+
static {
|
|
77
|
+
__name(this, "SuperAdminGuard");
|
|
78
|
+
}
|
|
79
|
+
canActivate(context) {
|
|
80
|
+
const request = context.switchToHttp().getRequest();
|
|
81
|
+
if (!request.user) throw new import_common.ForbiddenException("Nicht authentifiziert");
|
|
82
|
+
if (request.user.role !== "SUPER_ADMIN") {
|
|
83
|
+
throw new import_common.ForbiddenException("Nur SUPER_ADMIN-Rolle erlaubt");
|
|
84
|
+
}
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
SuperAdminGuard = _ts_decorate([
|
|
89
|
+
(0, import_common.Injectable)()
|
|
90
|
+
], SuperAdminGuard);
|
|
91
|
+
|
|
92
|
+
// src/admin/mfa.guard.ts
|
|
93
|
+
var import_common3 = require("@nestjs/common");
|
|
94
|
+
var import_core = require("@nestjs/core");
|
|
95
|
+
|
|
96
|
+
// src/admin/mfa.ts
|
|
97
|
+
var import_common2 = require("@nestjs/common");
|
|
98
|
+
var import_otplib = require("otplib");
|
|
99
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
100
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
101
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
102
|
+
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;
|
|
103
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
104
|
+
}
|
|
105
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
106
|
+
function _ts_metadata(k, v) {
|
|
107
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
108
|
+
}
|
|
109
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
110
|
+
function _ts_param(paramIndex, decorator) {
|
|
111
|
+
return function(target, key) {
|
|
112
|
+
decorator(target, key, paramIndex);
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
__name(_ts_param, "_ts_param");
|
|
116
|
+
var CLOCK_DRIFT_TOLERANCE_SECONDS = 30;
|
|
117
|
+
var OTPLIB_TOKEN_ERROR_NAMES = /* @__PURE__ */ new Set([
|
|
118
|
+
"TokenError",
|
|
119
|
+
"TokenFormatError",
|
|
120
|
+
"TokenLengthError"
|
|
121
|
+
]);
|
|
122
|
+
function isOtplibTokenError(error) {
|
|
123
|
+
return error instanceof Error && OTPLIB_TOKEN_ERROR_NAMES.has(error.name);
|
|
124
|
+
}
|
|
125
|
+
__name(isOtplibTokenError, "isOtplibTokenError");
|
|
126
|
+
var MfaService = class _MfaService {
|
|
127
|
+
static {
|
|
128
|
+
__name(this, "MfaService");
|
|
129
|
+
}
|
|
130
|
+
mfa;
|
|
131
|
+
logger = new import_common2.Logger(_MfaService.name);
|
|
132
|
+
constructor(mfa) {
|
|
133
|
+
this.mfa = mfa;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Generates a new TOTP secret, persists it via `MfaPort.setSecret`
|
|
137
|
+
* and returns the secret + the otpauth URI for the QR code.
|
|
138
|
+
*
|
|
139
|
+
* `issuer` and `label` shape the display in the authenticator (e.g.
|
|
140
|
+
* "DemoApp:taci@example.com").
|
|
141
|
+
*/
|
|
142
|
+
async setup(userId, label, issuer) {
|
|
143
|
+
const secret = (0, import_otplib.generateSecret)();
|
|
144
|
+
const otpauthUri = (0, import_otplib.generateURI)({
|
|
145
|
+
issuer,
|
|
146
|
+
label,
|
|
147
|
+
secret
|
|
148
|
+
});
|
|
149
|
+
await this.mfa.setSecret(userId, secret);
|
|
150
|
+
return {
|
|
151
|
+
secret,
|
|
152
|
+
otpauthUri
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Verifies the entered code against the stored secret,
|
|
157
|
+
* clock-drift-tolerant by ±1 time step.
|
|
158
|
+
*/
|
|
159
|
+
async verify(input) {
|
|
160
|
+
const secret = await this.mfa.getSecret(input.userId);
|
|
161
|
+
if (!secret) return false;
|
|
162
|
+
try {
|
|
163
|
+
const result = await (0, import_otplib.verify)({
|
|
164
|
+
secret,
|
|
165
|
+
token: input.code.trim(),
|
|
166
|
+
epochTolerance: CLOCK_DRIFT_TOLERANCE_SECONDS
|
|
167
|
+
});
|
|
168
|
+
return result.valid;
|
|
169
|
+
} catch (error) {
|
|
170
|
+
if (isOtplibTokenError(error)) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
174
|
+
this.logger.warn(`TOTP-Verify f\xFCr User ${input.userId} unerwartet fehlgeschlagen: ${message}`);
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Deletes a user's secret — used by `ahp admin mfa-reset`.
|
|
180
|
+
*/
|
|
181
|
+
async disable(userId) {
|
|
182
|
+
await this.mfa.setSecret(userId, null);
|
|
183
|
+
}
|
|
184
|
+
/** Delegates to `MfaPort.isEnabled`. */
|
|
185
|
+
async isEnabled(userId) {
|
|
186
|
+
return this.mfa.isEnabled(userId);
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
MfaService = _ts_decorate2([
|
|
190
|
+
(0, import_common2.Injectable)(),
|
|
191
|
+
_ts_param(0, (0, import_common2.Inject)(MFA_PORT_TOKEN)),
|
|
192
|
+
_ts_metadata("design:type", Function),
|
|
193
|
+
_ts_metadata("design:paramtypes", [
|
|
194
|
+
typeof MfaPort === "undefined" ? Object : MfaPort
|
|
195
|
+
])
|
|
196
|
+
], MfaService);
|
|
197
|
+
|
|
198
|
+
// src/admin/mfa.guard.ts
|
|
199
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
200
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
201
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
202
|
+
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;
|
|
203
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
204
|
+
}
|
|
205
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
206
|
+
function _ts_metadata2(k, v) {
|
|
207
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
208
|
+
}
|
|
209
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
210
|
+
function _ts_param2(paramIndex, decorator) {
|
|
211
|
+
return function(target, key) {
|
|
212
|
+
decorator(target, key, paramIndex);
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
__name(_ts_param2, "_ts_param");
|
|
216
|
+
var REQUIRE_MFA_KEY = "saas-platform/require-mfa";
|
|
217
|
+
var RequireMfa = /* @__PURE__ */ __name(() => (0, import_common3.SetMetadata)(REQUIRE_MFA_KEY, true), "RequireMfa");
|
|
218
|
+
var MfaGuard = class _MfaGuard {
|
|
219
|
+
static {
|
|
220
|
+
__name(this, "MfaGuard");
|
|
221
|
+
}
|
|
222
|
+
reflector;
|
|
223
|
+
mfaService;
|
|
224
|
+
logger = new import_common3.Logger(_MfaGuard.name);
|
|
225
|
+
constructor(reflector, mfaService) {
|
|
226
|
+
this.reflector = reflector;
|
|
227
|
+
this.mfaService = mfaService;
|
|
228
|
+
}
|
|
229
|
+
async canActivate(context) {
|
|
230
|
+
const required = this.reflector.getAllAndOverride(REQUIRE_MFA_KEY, [
|
|
231
|
+
context.getHandler(),
|
|
232
|
+
context.getClass()
|
|
233
|
+
]);
|
|
234
|
+
if (!required) return true;
|
|
235
|
+
if (process.env.SAAS_PLATFORM_SKIP_MFA === "1" && process.env.NODE_ENV !== "production") {
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
const request = context.switchToHttp().getRequest();
|
|
239
|
+
const user = request.user;
|
|
240
|
+
if (!user) throw new import_common3.UnauthorizedException({
|
|
241
|
+
reason: "NOT_AUTHENTICATED"
|
|
242
|
+
});
|
|
243
|
+
const enabled = await this.mfaService.isEnabled(user.id);
|
|
244
|
+
if (!enabled) {
|
|
245
|
+
throw new import_common3.UnauthorizedException({
|
|
246
|
+
reason: "MFA_NOT_SET_UP",
|
|
247
|
+
message: "Bitte zuerst MFA-Setup \xFCber das CLI ausf\xFChren."
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
const headerVal = request.headers?.["x-mfa-code"];
|
|
251
|
+
const code = Array.isArray(headerVal) ? headerVal[0] : headerVal;
|
|
252
|
+
if (!code) {
|
|
253
|
+
throw new import_common3.UnauthorizedException({
|
|
254
|
+
reason: "MFA_REQUIRED",
|
|
255
|
+
message: "TOTP-Code im Header X-Mfa-Code erforderlich."
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
const valid = await this.mfaService.verify({
|
|
259
|
+
userId: user.id,
|
|
260
|
+
code: String(code)
|
|
261
|
+
});
|
|
262
|
+
if (!valid) {
|
|
263
|
+
throw new import_common3.UnauthorizedException({
|
|
264
|
+
reason: "MFA_FAILED",
|
|
265
|
+
message: "TOTP-Code ung\xFCltig."
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
MfaGuard = _ts_decorate3([
|
|
272
|
+
(0, import_common3.Injectable)(),
|
|
273
|
+
_ts_param2(0, (0, import_common3.Inject)(import_core.Reflector)),
|
|
274
|
+
_ts_metadata2("design:type", Function),
|
|
275
|
+
_ts_metadata2("design:paramtypes", [
|
|
276
|
+
typeof import_core.Reflector === "undefined" ? Object : import_core.Reflector,
|
|
277
|
+
typeof MfaService === "undefined" ? Object : MfaService
|
|
278
|
+
])
|
|
279
|
+
], MfaGuard);
|
|
280
|
+
|
|
281
|
+
// src/admin/admin-audit.service.ts
|
|
282
|
+
var os = __toESM(require("os"), 1);
|
|
283
|
+
var import_common4 = require("@nestjs/common");
|
|
284
|
+
function _ts_decorate4(decorators, target, key, desc) {
|
|
285
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
286
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
287
|
+
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;
|
|
288
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
289
|
+
}
|
|
290
|
+
__name(_ts_decorate4, "_ts_decorate");
|
|
291
|
+
function _ts_metadata3(k, v) {
|
|
292
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
293
|
+
}
|
|
294
|
+
__name(_ts_metadata3, "_ts_metadata");
|
|
295
|
+
function _ts_param3(paramIndex, decorator) {
|
|
296
|
+
return function(target, key) {
|
|
297
|
+
decorator(target, key, paramIndex);
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
__name(_ts_param3, "_ts_param");
|
|
301
|
+
var AdminAuditService = class {
|
|
302
|
+
static {
|
|
303
|
+
__name(this, "AdminAuditService");
|
|
304
|
+
}
|
|
305
|
+
audit;
|
|
306
|
+
constructor(audit) {
|
|
307
|
+
this.audit = audit;
|
|
308
|
+
}
|
|
309
|
+
async log(input) {
|
|
310
|
+
await this.audit.write({
|
|
311
|
+
actor: input.actor,
|
|
312
|
+
entity: input.entity,
|
|
313
|
+
entityId: input.entityId,
|
|
314
|
+
action: input.action,
|
|
315
|
+
changes: {
|
|
316
|
+
...input.changes ?? {},
|
|
317
|
+
actor: this.actorTag(input.actor)
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Standardized actor tag for the `changes.actor` column:
|
|
323
|
+
* `<source>:<email>:<context>`.
|
|
324
|
+
*/
|
|
325
|
+
actorTag(actor) {
|
|
326
|
+
return `${actor.source}:${actor.email}:${actor.context}`;
|
|
327
|
+
}
|
|
328
|
+
/** Helper: build an AdminActor from an authenticated web request. */
|
|
329
|
+
fromWebRequest(user, sessionId) {
|
|
330
|
+
return {
|
|
331
|
+
userId: user.id,
|
|
332
|
+
email: user.email,
|
|
333
|
+
source: "web",
|
|
334
|
+
context: sessionId ?? "unknown"
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
/** Helper: build an AdminActor from a CLI identity (hostname as context). */
|
|
338
|
+
fromCli(user) {
|
|
339
|
+
return {
|
|
340
|
+
userId: user.id,
|
|
341
|
+
email: user.email,
|
|
342
|
+
source: "cli",
|
|
343
|
+
context: os.hostname()
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
AdminAuditService = _ts_decorate4([
|
|
348
|
+
(0, import_common4.Injectable)(),
|
|
349
|
+
_ts_param3(0, (0, import_common4.Inject)(AUDIT_PORT_TOKEN)),
|
|
350
|
+
_ts_metadata3("design:type", Function),
|
|
351
|
+
_ts_metadata3("design:paramtypes", [
|
|
352
|
+
typeof AuditPort === "undefined" ? Object : AuditPort
|
|
353
|
+
])
|
|
354
|
+
], AdminAuditService);
|
|
355
|
+
|
|
356
|
+
// src/admin/admin-bypass-rls.interceptor.ts
|
|
357
|
+
var import_common5 = require("@nestjs/common");
|
|
358
|
+
var import_rxjs = require("rxjs");
|
|
359
|
+
var import_operators = require("rxjs/operators");
|
|
360
|
+
function _ts_decorate5(decorators, target, key, desc) {
|
|
361
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
362
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
363
|
+
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;
|
|
364
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
365
|
+
}
|
|
366
|
+
__name(_ts_decorate5, "_ts_decorate");
|
|
367
|
+
function _ts_metadata4(k, v) {
|
|
368
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
369
|
+
}
|
|
370
|
+
__name(_ts_metadata4, "_ts_metadata");
|
|
371
|
+
function _ts_param4(paramIndex, decorator) {
|
|
372
|
+
return function(target, key) {
|
|
373
|
+
decorator(target, key, paramIndex);
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
__name(_ts_param4, "_ts_param");
|
|
377
|
+
var AdminBypassRlsInterceptor = class {
|
|
378
|
+
static {
|
|
379
|
+
__name(this, "AdminBypassRlsInterceptor");
|
|
380
|
+
}
|
|
381
|
+
port;
|
|
382
|
+
constructor(port) {
|
|
383
|
+
this.port = port;
|
|
384
|
+
}
|
|
385
|
+
intercept(_context, next) {
|
|
386
|
+
return (0, import_rxjs.defer)(() => (0, import_rxjs.from)(this.port.runWithBypass(async () => {
|
|
387
|
+
return next.handle();
|
|
388
|
+
})).pipe((0, import_operators.switchAll)()));
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
AdminBypassRlsInterceptor = _ts_decorate5([
|
|
392
|
+
(0, import_common5.Injectable)(),
|
|
393
|
+
_ts_param4(0, (0, import_common5.Inject)(RLS_BYPASS_PORT_TOKEN)),
|
|
394
|
+
_ts_metadata4("design:type", Function),
|
|
395
|
+
_ts_metadata4("design:paramtypes", [
|
|
396
|
+
typeof RlsBypassPort === "undefined" ? Object : RlsBypassPort
|
|
397
|
+
])
|
|
398
|
+
], AdminBypassRlsInterceptor);
|
|
399
|
+
|
|
400
|
+
// src/admin/module.ts
|
|
401
|
+
var import_common6 = require("@nestjs/common");
|
|
402
|
+
|
|
403
|
+
// src/core/di.ts
|
|
404
|
+
function asProvider(token, impl) {
|
|
405
|
+
if (typeof impl === "object" && impl !== null && "useFactory" in impl && typeof impl.useFactory === "function") {
|
|
406
|
+
const factory = impl;
|
|
407
|
+
return {
|
|
408
|
+
provide: token,
|
|
409
|
+
useFactory: factory.useFactory,
|
|
410
|
+
inject: factory.inject
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
return {
|
|
414
|
+
provide: token,
|
|
415
|
+
useValue: impl
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
__name(asProvider, "asProvider");
|
|
419
|
+
|
|
420
|
+
// src/admin/module.ts
|
|
421
|
+
function _ts_decorate6(decorators, target, key, desc) {
|
|
422
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
423
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
424
|
+
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;
|
|
425
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
426
|
+
}
|
|
427
|
+
__name(_ts_decorate6, "_ts_decorate");
|
|
428
|
+
var AdminModule = class _AdminModule {
|
|
429
|
+
static {
|
|
430
|
+
__name(this, "AdminModule");
|
|
431
|
+
}
|
|
432
|
+
static forRoot(options) {
|
|
433
|
+
const providers = [
|
|
434
|
+
asProvider(MFA_PORT_TOKEN, options.mfaPort),
|
|
435
|
+
asProvider(AUDIT_PORT_TOKEN, options.auditPort),
|
|
436
|
+
asProvider(RLS_BYPASS_PORT_TOKEN, options.rlsBypassPort),
|
|
437
|
+
MfaService,
|
|
438
|
+
AdminAuditService,
|
|
439
|
+
SuperAdminGuard,
|
|
440
|
+
MfaGuard,
|
|
441
|
+
AdminBypassRlsInterceptor
|
|
442
|
+
];
|
|
443
|
+
return {
|
|
444
|
+
module: _AdminModule,
|
|
445
|
+
global: options.global ?? false,
|
|
446
|
+
providers,
|
|
447
|
+
exports: [
|
|
448
|
+
MFA_PORT_TOKEN,
|
|
449
|
+
AUDIT_PORT_TOKEN,
|
|
450
|
+
RLS_BYPASS_PORT_TOKEN,
|
|
451
|
+
MfaService,
|
|
452
|
+
AdminAuditService,
|
|
453
|
+
SuperAdminGuard,
|
|
454
|
+
MfaGuard,
|
|
455
|
+
AdminBypassRlsInterceptor
|
|
456
|
+
]
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
AdminModule = _ts_decorate6([
|
|
461
|
+
(0, import_common6.Module)({})
|
|
462
|
+
], AdminModule);
|
|
463
|
+
|
|
464
|
+
// src/admin/admin-manifest.config.ts
|
|
465
|
+
var ADMIN_MANIFEST_CONFIG = /* @__PURE__ */ Symbol("ADMIN_MANIFEST_CONFIG");
|
|
466
|
+
|
|
467
|
+
// src/admin/admin-manifest.service.ts
|
|
468
|
+
var import_common7 = require("@nestjs/common");
|
|
469
|
+
var import_node_crypto = require("crypto");
|
|
470
|
+
function _ts_decorate7(decorators, target, key, desc) {
|
|
471
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
472
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
473
|
+
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;
|
|
474
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
475
|
+
}
|
|
476
|
+
__name(_ts_decorate7, "_ts_decorate");
|
|
477
|
+
function _ts_metadata5(k, v) {
|
|
478
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
479
|
+
}
|
|
480
|
+
__name(_ts_metadata5, "_ts_metadata");
|
|
481
|
+
function _ts_param5(paramIndex, decorator) {
|
|
482
|
+
return function(target, key) {
|
|
483
|
+
decorator(target, key, paramIndex);
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
__name(_ts_param5, "_ts_param");
|
|
487
|
+
var PLATFORM_CORE_CONTRIBUTION_TOKEN = /* @__PURE__ */ Symbol("PLATFORM_CORE_CONTRIBUTION");
|
|
488
|
+
var AdminManifestService = class _AdminManifestService {
|
|
489
|
+
static {
|
|
490
|
+
__name(this, "AdminManifestService");
|
|
491
|
+
}
|
|
492
|
+
config;
|
|
493
|
+
logger = new import_common7.Logger(_AdminManifestService.name);
|
|
494
|
+
contributions = [];
|
|
495
|
+
cached = null;
|
|
496
|
+
constructor(config, platformCore = null) {
|
|
497
|
+
this.config = config;
|
|
498
|
+
if (platformCore) {
|
|
499
|
+
this.contributions.push(platformCore);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
register(contribution) {
|
|
503
|
+
this.contributions.push(contribution);
|
|
504
|
+
this.cached = null;
|
|
505
|
+
}
|
|
506
|
+
getManifest() {
|
|
507
|
+
if (this.cached) return this.cached;
|
|
508
|
+
this.cached = this.build();
|
|
509
|
+
this.logger.log(`Manifest built: ${this.contributions.length} contribution(s), hash=${this.cached.build.manifestHash.slice(0, 24)}\u2026`);
|
|
510
|
+
return this.cached;
|
|
511
|
+
}
|
|
512
|
+
rebuild() {
|
|
513
|
+
this.cached = null;
|
|
514
|
+
return this.getManifest();
|
|
515
|
+
}
|
|
516
|
+
build() {
|
|
517
|
+
const merged = this.mergeContributions(this.contributions);
|
|
518
|
+
const draft = {
|
|
519
|
+
schemaVersion: 1,
|
|
520
|
+
project: this.config.project,
|
|
521
|
+
build: {
|
|
522
|
+
...this.config.build,
|
|
523
|
+
manifestHash: "sha256-pending"
|
|
524
|
+
},
|
|
525
|
+
planCatalogSnapshot: this.config.planCatalogSnapshot,
|
|
526
|
+
capabilities: merged.capabilities,
|
|
527
|
+
navigation: merged.navigation,
|
|
528
|
+
dashboard: merged.dashboard,
|
|
529
|
+
tenants: merged.tenants,
|
|
530
|
+
audit: merged.audit
|
|
531
|
+
};
|
|
532
|
+
return {
|
|
533
|
+
...draft,
|
|
534
|
+
build: {
|
|
535
|
+
...draft.build,
|
|
536
|
+
manifestHash: this.computeHash(draft)
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
mergeContributions(contributions) {
|
|
541
|
+
const capabilities = {};
|
|
542
|
+
const standardPages = {};
|
|
543
|
+
const projectPages = [];
|
|
544
|
+
const kpiCards = [];
|
|
545
|
+
const tenantColumns = [];
|
|
546
|
+
const tenantActions = [];
|
|
547
|
+
const auditActions = [];
|
|
548
|
+
for (const c of contributions) {
|
|
549
|
+
if (c.capabilities) Object.assign(capabilities, c.capabilities);
|
|
550
|
+
if (c.navigation?.standardPages) Object.assign(standardPages, c.navigation.standardPages);
|
|
551
|
+
if (c.navigation?.projectPages) projectPages.push(...c.navigation.projectPages);
|
|
552
|
+
if (c.dashboard?.kpiCards) kpiCards.push(...c.dashboard.kpiCards);
|
|
553
|
+
if (c.tenants?.columns) tenantColumns.push(...c.tenants.columns);
|
|
554
|
+
if (c.tenants?.actions) tenantActions.push(...c.tenants.actions);
|
|
555
|
+
if (c.audit?.actions) auditActions.push(...c.audit.actions);
|
|
556
|
+
}
|
|
557
|
+
kpiCards.sort((a, b) => (b.slotPriority ?? 0) - (a.slotPriority ?? 0));
|
|
558
|
+
return {
|
|
559
|
+
capabilities,
|
|
560
|
+
navigation: {
|
|
561
|
+
standardPages,
|
|
562
|
+
projectPages
|
|
563
|
+
},
|
|
564
|
+
dashboard: kpiCards.length > 0 ? {
|
|
565
|
+
kpiCards
|
|
566
|
+
} : void 0,
|
|
567
|
+
tenants: tenantColumns.length > 0 || tenantActions.length > 0 ? {
|
|
568
|
+
columns: tenantColumns,
|
|
569
|
+
actions: tenantActions
|
|
570
|
+
} : void 0,
|
|
571
|
+
audit: auditActions.length > 0 ? {
|
|
572
|
+
actions: auditActions
|
|
573
|
+
} : void 0
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Deterministic SHA-256 hash over the manifest. Uses the insertion
|
|
578
|
+
* order of the object keys — so that semantically meaningful reorders (e.g.
|
|
579
|
+
* the order of the sidebar items in `navigation.standardPages`) change the
|
|
580
|
+
* hash and invalidate the browser ETag cache. The manifest's own
|
|
581
|
+
* `manifestHash` field is hidden before serialization.
|
|
582
|
+
*/
|
|
583
|
+
computeHash(manifest) {
|
|
584
|
+
const canonical = stableStringify({
|
|
585
|
+
...manifest,
|
|
586
|
+
build: {
|
|
587
|
+
...manifest.build,
|
|
588
|
+
manifestHash: void 0
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
const digest = (0, import_node_crypto.createHash)("sha256").update(canonical).digest("base64url");
|
|
592
|
+
return `sha256-${digest}`;
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
AdminManifestService = _ts_decorate7([
|
|
596
|
+
(0, import_common7.Injectable)(),
|
|
597
|
+
_ts_param5(0, (0, import_common7.Inject)(ADMIN_MANIFEST_CONFIG)),
|
|
598
|
+
_ts_param5(1, (0, import_common7.Optional)()),
|
|
599
|
+
_ts_param5(1, (0, import_common7.Inject)(PLATFORM_CORE_CONTRIBUTION_TOKEN)),
|
|
600
|
+
_ts_metadata5("design:type", Function),
|
|
601
|
+
_ts_metadata5("design:paramtypes", [
|
|
602
|
+
typeof AdminManifestConfig === "undefined" ? Object : AdminManifestConfig,
|
|
603
|
+
Object
|
|
604
|
+
])
|
|
605
|
+
], AdminManifestService);
|
|
606
|
+
function stableStringify(value) {
|
|
607
|
+
if (value === null) return "null";
|
|
608
|
+
if (value === void 0) return "null";
|
|
609
|
+
if (typeof value === "number") return Number.isFinite(value) ? String(value) : "null";
|
|
610
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
611
|
+
if (typeof value === "string") return JSON.stringify(value);
|
|
612
|
+
if (Array.isArray(value)) {
|
|
613
|
+
return "[" + value.map(stableStringify).join(",") + "]";
|
|
614
|
+
}
|
|
615
|
+
if (typeof value === "object") {
|
|
616
|
+
const obj = value;
|
|
617
|
+
const keys = Object.keys(obj).filter((k) => obj[k] !== void 0);
|
|
618
|
+
return "{" + keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") + "}";
|
|
619
|
+
}
|
|
620
|
+
return JSON.stringify(value);
|
|
621
|
+
}
|
|
622
|
+
__name(stableStringify, "stableStringify");
|
|
623
|
+
|
|
624
|
+
// src/admin/admin-public-boot.controller.ts
|
|
625
|
+
var import_common8 = require("@nestjs/common");
|
|
626
|
+
function _ts_decorate8(decorators, target, key, desc) {
|
|
627
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
628
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
629
|
+
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;
|
|
630
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
631
|
+
}
|
|
632
|
+
__name(_ts_decorate8, "_ts_decorate");
|
|
633
|
+
function _ts_metadata6(k, v) {
|
|
634
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
635
|
+
}
|
|
636
|
+
__name(_ts_metadata6, "_ts_metadata");
|
|
637
|
+
function _ts_param6(paramIndex, decorator) {
|
|
638
|
+
return function(target, key) {
|
|
639
|
+
decorator(target, key, paramIndex);
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
__name(_ts_param6, "_ts_param");
|
|
643
|
+
var AdminPublicBootController = class {
|
|
644
|
+
static {
|
|
645
|
+
__name(this, "AdminPublicBootController");
|
|
646
|
+
}
|
|
647
|
+
config;
|
|
648
|
+
constructor(config) {
|
|
649
|
+
this.config = config;
|
|
650
|
+
}
|
|
651
|
+
getBoot() {
|
|
652
|
+
return {
|
|
653
|
+
project: {
|
|
654
|
+
key: this.config.project.key,
|
|
655
|
+
displayName: this.config.project.displayName,
|
|
656
|
+
label: this.config.project.label,
|
|
657
|
+
icon: this.config.project.icon,
|
|
658
|
+
logoUrl: this.config.project.logoUrl,
|
|
659
|
+
environment: this.config.project.environment
|
|
660
|
+
}
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
_ts_decorate8([
|
|
665
|
+
(0, import_common8.Get)("boot"),
|
|
666
|
+
_ts_metadata6("design:type", Function),
|
|
667
|
+
_ts_metadata6("design:paramtypes", []),
|
|
668
|
+
_ts_metadata6("design:returntype", typeof PublicBootResponse === "undefined" ? Object : PublicBootResponse)
|
|
669
|
+
], AdminPublicBootController.prototype, "getBoot", null);
|
|
670
|
+
AdminPublicBootController = _ts_decorate8([
|
|
671
|
+
(0, import_common8.Controller)("admin"),
|
|
672
|
+
_ts_param6(0, (0, import_common8.Inject)(ADMIN_MANIFEST_CONFIG)),
|
|
673
|
+
_ts_metadata6("design:type", Function),
|
|
674
|
+
_ts_metadata6("design:paramtypes", [
|
|
675
|
+
typeof AdminManifestConfig === "undefined" ? Object : AdminManifestConfig
|
|
676
|
+
])
|
|
677
|
+
], AdminPublicBootController);
|
|
678
|
+
|
|
679
|
+
// src/admin/admin-manifest.module.ts
|
|
680
|
+
var import_common9 = require("@nestjs/common");
|
|
681
|
+
|
|
682
|
+
// src/admin/manifest-core.ts
|
|
683
|
+
var PLATFORM_CORE_MANIFEST_CONTRIBUTION = {
|
|
684
|
+
navigation: {
|
|
685
|
+
// Key order is render order in the sidebar (within the
|
|
686
|
+
// section, see `DEFAULT_NAV_SECTIONS` in the nav-builder). The order per
|
|
687
|
+
// section is deliberately curated:
|
|
688
|
+
// Overview: dashboard
|
|
689
|
+
// Product catalog: discovery → bundles → businessTypes → plans →
|
|
690
|
+
// planVersions → marketingCatalog → promoCodes
|
|
691
|
+
// (promoCodes is appended by the app contributions
|
|
692
|
+
// and therefore lands at the end of the section)
|
|
693
|
+
// Customers: tenants → users → pilots
|
|
694
|
+
// System: audit
|
|
695
|
+
standardPages: {
|
|
696
|
+
dashboard: {
|
|
697
|
+
enabled: true,
|
|
698
|
+
requiredCapability: "dashboard.read"
|
|
699
|
+
},
|
|
700
|
+
// SPEC_V2 §3.3 — discovery snapshot of the running backend.
|
|
701
|
+
// Apps must set `discovery.read` in their manifest capabilities
|
|
702
|
+
// to `true` so that the NavBuilder wires the page into the
|
|
703
|
+
// sidebar; otherwise it is filtered out automatically.
|
|
704
|
+
discovery: {
|
|
705
|
+
enabled: true,
|
|
706
|
+
requiredCapability: "discovery.read"
|
|
707
|
+
},
|
|
708
|
+
// SPEC_V2 §11.1 M3 — Bundle editor in SuperAdmin.
|
|
709
|
+
// Apps with a DB-driven catalog set `bundles.read = true`.
|
|
710
|
+
bundles: {
|
|
711
|
+
enabled: true,
|
|
712
|
+
requiredCapability: "bundles.read"
|
|
713
|
+
},
|
|
714
|
+
// SPEC_V2 §11.1 M3 — BusinessType editor in SuperAdmin.
|
|
715
|
+
// Apps with domain verticals set `businessTypes.read = true`.
|
|
716
|
+
businessTypes: {
|
|
717
|
+
enabled: true,
|
|
718
|
+
requiredCapability: "businessTypes.read"
|
|
719
|
+
},
|
|
720
|
+
plans: {
|
|
721
|
+
enabled: true,
|
|
722
|
+
requiredCapability: "plans.read"
|
|
723
|
+
},
|
|
724
|
+
planVersions: {
|
|
725
|
+
enabled: true,
|
|
726
|
+
requiredCapability: "plans.read"
|
|
727
|
+
},
|
|
728
|
+
// SPEC_V2 §11.1 M3 — marketing catalog (locale pivot).
|
|
729
|
+
// Apps that market a public catalog set
|
|
730
|
+
// `marketingProjections.read = true`.
|
|
731
|
+
marketingCatalog: {
|
|
732
|
+
enabled: true,
|
|
733
|
+
requiredCapability: "marketingProjections.read"
|
|
734
|
+
},
|
|
735
|
+
tenants: {
|
|
736
|
+
enabled: true,
|
|
737
|
+
requiredCapability: "tenants.read"
|
|
738
|
+
},
|
|
739
|
+
users: {
|
|
740
|
+
enabled: true,
|
|
741
|
+
requiredCapability: "users.read"
|
|
742
|
+
},
|
|
743
|
+
pilots: {
|
|
744
|
+
enabled: true,
|
|
745
|
+
requiredCapability: "pilots.read"
|
|
746
|
+
},
|
|
747
|
+
// Audit log deliberately at the end — rarely needed, should
|
|
748
|
+
// not obscure the productive pages.
|
|
749
|
+
audit: {
|
|
750
|
+
enabled: true,
|
|
751
|
+
requiredCapability: "audit.read"
|
|
752
|
+
},
|
|
753
|
+
// Platform email sender (system/registration mails). Apps
|
|
754
|
+
// set `platformEmail.read = true` so that the NavBuilder wires the page
|
|
755
|
+
// in; otherwise it is filtered out automatically.
|
|
756
|
+
platformEmail: {
|
|
757
|
+
enabled: true,
|
|
758
|
+
requiredCapability: "platformEmail.read"
|
|
759
|
+
},
|
|
760
|
+
// Platform email history (audit of the sent system mails). Apps
|
|
761
|
+
// set `platformEmailHistory.read = true` so that the NavBuilder wires the
|
|
762
|
+
// page in; otherwise it is filtered out automatically.
|
|
763
|
+
platformEmailHistory: {
|
|
764
|
+
enabled: true,
|
|
765
|
+
requiredCapability: "platformEmailHistory.read"
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
tenants: {
|
|
770
|
+
actions: [
|
|
771
|
+
{
|
|
772
|
+
id: "platform.tenants.suspend",
|
|
773
|
+
label: "Mandant suspendieren",
|
|
774
|
+
actionKey: "tenants.suspend",
|
|
775
|
+
requiredCapability: "tenants.suspend",
|
|
776
|
+
requiresMfa: true,
|
|
777
|
+
confirmType: "typed-slug"
|
|
778
|
+
},
|
|
779
|
+
{
|
|
780
|
+
id: "platform.tenants.reactivate",
|
|
781
|
+
label: "Mandant reaktivieren",
|
|
782
|
+
actionKey: "tenants.reactivate",
|
|
783
|
+
requiredCapability: "tenants.reactivate",
|
|
784
|
+
requiresMfa: true,
|
|
785
|
+
confirmType: "simple"
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
id: "platform.tenants.impersonate",
|
|
789
|
+
label: "Impersonate",
|
|
790
|
+
actionKey: "tenants.impersonate",
|
|
791
|
+
requiredCapability: "tenants.impersonate",
|
|
792
|
+
requiresMfa: true,
|
|
793
|
+
confirmType: "simple"
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
id: "platform.tenants.export",
|
|
797
|
+
label: "DSGVO-Export",
|
|
798
|
+
actionKey: "tenants.export",
|
|
799
|
+
requiredCapability: "tenants.export",
|
|
800
|
+
requiresMfa: true,
|
|
801
|
+
confirmType: "simple"
|
|
802
|
+
},
|
|
803
|
+
{
|
|
804
|
+
id: "platform.subscriptions.cancel",
|
|
805
|
+
label: "Subscription k\xFCndigen",
|
|
806
|
+
actionKey: "subscriptions.cancel",
|
|
807
|
+
requiredCapability: "subscriptions.cancel",
|
|
808
|
+
requiresMfa: true,
|
|
809
|
+
confirmType: "typed-slug"
|
|
810
|
+
},
|
|
811
|
+
{
|
|
812
|
+
id: "platform.pilots.grant",
|
|
813
|
+
label: "Pilot-Status setzen",
|
|
814
|
+
actionKey: "pilots.grant",
|
|
815
|
+
requiredCapability: "pilots.grant",
|
|
816
|
+
requiresMfa: true,
|
|
817
|
+
confirmType: "simple"
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
id: "platform.pilots.revoke",
|
|
821
|
+
label: "Pilot-Status entziehen",
|
|
822
|
+
actionKey: "pilots.revoke",
|
|
823
|
+
requiredCapability: "pilots.revoke",
|
|
824
|
+
requiresMfa: true,
|
|
825
|
+
confirmType: "typed-slug"
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
id: "platform.pilots.extend",
|
|
829
|
+
label: "Pilot verl\xE4ngern",
|
|
830
|
+
actionKey: "pilots.extend",
|
|
831
|
+
requiredCapability: "pilots.extend",
|
|
832
|
+
requiresMfa: true,
|
|
833
|
+
confirmType: "date"
|
|
834
|
+
}
|
|
835
|
+
]
|
|
836
|
+
},
|
|
837
|
+
audit: {
|
|
838
|
+
actions: [
|
|
839
|
+
{
|
|
840
|
+
key: "TENANT_SUSPEND",
|
|
841
|
+
label: "Mandant suspendiert",
|
|
842
|
+
severity: "high"
|
|
843
|
+
},
|
|
844
|
+
{
|
|
845
|
+
key: "TENANT_REACTIVATE",
|
|
846
|
+
label: "Mandant reaktiviert",
|
|
847
|
+
severity: "medium"
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
key: "TENANT_IMPERSONATE",
|
|
851
|
+
label: "Impersonation gestartet",
|
|
852
|
+
severity: "high"
|
|
853
|
+
},
|
|
854
|
+
{
|
|
855
|
+
key: "TENANT_EXPORT",
|
|
856
|
+
label: "DSGVO-Export ausgel\xF6st",
|
|
857
|
+
severity: "medium"
|
|
858
|
+
},
|
|
859
|
+
{
|
|
860
|
+
key: "PILOT_CREATE",
|
|
861
|
+
label: "Pilot-Tenant angelegt",
|
|
862
|
+
severity: "medium"
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
key: "PILOT_GRANT",
|
|
866
|
+
label: "Pilot-Status gesetzt",
|
|
867
|
+
severity: "medium"
|
|
868
|
+
},
|
|
869
|
+
{
|
|
870
|
+
key: "PILOT_REVOKE",
|
|
871
|
+
label: "Pilot-Status entzogen",
|
|
872
|
+
severity: "medium"
|
|
873
|
+
},
|
|
874
|
+
{
|
|
875
|
+
key: "PILOT_EXTEND",
|
|
876
|
+
label: "Pilot verl\xE4ngert",
|
|
877
|
+
severity: "low"
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
key: "PLAN_VERSION_PUBLISH",
|
|
881
|
+
label: "Plan-Version freigegeben",
|
|
882
|
+
severity: "high"
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
key: "PLAN_VERSION_TERMINATE",
|
|
886
|
+
label: "Plan-Version terminiert",
|
|
887
|
+
severity: "high"
|
|
888
|
+
},
|
|
889
|
+
{
|
|
890
|
+
key: "SUBSCRIPTION_CANCEL",
|
|
891
|
+
label: "Subscription gek\xFCndigt",
|
|
892
|
+
severity: "high"
|
|
893
|
+
},
|
|
894
|
+
{
|
|
895
|
+
key: "USER_RESET_PASSWORD",
|
|
896
|
+
label: "Passwort-Reset ausgel\xF6st",
|
|
897
|
+
severity: "medium"
|
|
898
|
+
},
|
|
899
|
+
{
|
|
900
|
+
key: "USER_DEACTIVATE",
|
|
901
|
+
label: "User deaktiviert",
|
|
902
|
+
severity: "high"
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
key: "USER_REASSIGN_ADMIN",
|
|
906
|
+
label: "Admin-Rolle \xFCbertragen",
|
|
907
|
+
severity: "high"
|
|
908
|
+
},
|
|
909
|
+
{
|
|
910
|
+
key: "PLATFORM_EMAIL_PROVIDER_CREATE",
|
|
911
|
+
label: "Plattform-Absender angelegt",
|
|
912
|
+
severity: "medium"
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
key: "PLATFORM_EMAIL_PROVIDER_UPDATE",
|
|
916
|
+
label: "Plattform-Absender ge\xE4ndert",
|
|
917
|
+
severity: "medium"
|
|
918
|
+
},
|
|
919
|
+
{
|
|
920
|
+
key: "PLATFORM_EMAIL_PROVIDER_DELETE",
|
|
921
|
+
label: "Plattform-Absender gel\xF6scht",
|
|
922
|
+
severity: "medium"
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
key: "PLATFORM_EMAIL_PROVIDER_TEST",
|
|
926
|
+
label: "Plattform-Absender Test-Versand",
|
|
927
|
+
severity: "low"
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
key: "EMAIL_HISTORY_DELETE",
|
|
931
|
+
label: "Plattform-E-Mail aus Verlauf entfernt",
|
|
932
|
+
severity: "medium"
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
key: "EMAIL_HISTORY_RESEND",
|
|
936
|
+
label: "Plattform-E-Mail erneut versendet",
|
|
937
|
+
severity: "low"
|
|
938
|
+
}
|
|
939
|
+
]
|
|
940
|
+
}
|
|
941
|
+
};
|
|
942
|
+
|
|
943
|
+
// src/admin/admin-manifest.module.ts
|
|
944
|
+
function _ts_decorate9(decorators, target, key, desc) {
|
|
945
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
946
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
947
|
+
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;
|
|
948
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
949
|
+
}
|
|
950
|
+
__name(_ts_decorate9, "_ts_decorate");
|
|
951
|
+
function _ts_metadata7(k, v) {
|
|
952
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
953
|
+
}
|
|
954
|
+
__name(_ts_metadata7, "_ts_metadata");
|
|
955
|
+
function _ts_param7(paramIndex, decorator) {
|
|
956
|
+
return function(target, key) {
|
|
957
|
+
decorator(target, key, paramIndex);
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
__name(_ts_param7, "_ts_param");
|
|
961
|
+
function asConfigProvider(impl) {
|
|
962
|
+
if (typeof impl === "object" && impl !== null && "useFactory" in impl && typeof impl.useFactory === "function") {
|
|
963
|
+
return {
|
|
964
|
+
provide: ADMIN_MANIFEST_CONFIG,
|
|
965
|
+
useFactory: impl.useFactory,
|
|
966
|
+
inject: impl.inject
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
return {
|
|
970
|
+
provide: ADMIN_MANIFEST_CONFIG,
|
|
971
|
+
useValue: impl
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
__name(asConfigProvider, "asConfigProvider");
|
|
975
|
+
function buildManifestController(guards, reloadGuards) {
|
|
976
|
+
const reloadChain = [
|
|
977
|
+
...guards,
|
|
978
|
+
...reloadGuards
|
|
979
|
+
];
|
|
980
|
+
let GeneratedAdminManifestController = class GeneratedAdminManifestController {
|
|
981
|
+
static {
|
|
982
|
+
__name(this, "GeneratedAdminManifestController");
|
|
983
|
+
}
|
|
984
|
+
manifest;
|
|
985
|
+
// Explicit @Inject instead of type reflection: tsup/esbuild do not emit
|
|
986
|
+
// `design:paramtypes` metadata, so Nest cannot otherwise resolve the
|
|
987
|
+
// service type at the constructor.
|
|
988
|
+
constructor(manifest) {
|
|
989
|
+
this.manifest = manifest;
|
|
990
|
+
}
|
|
991
|
+
getManifest(ifNoneMatch, res) {
|
|
992
|
+
const m = this.manifest.getManifest();
|
|
993
|
+
const etag = `"${m.build.manifestHash}"`;
|
|
994
|
+
res.header("ETag", etag);
|
|
995
|
+
if (ifNoneMatch && ifNoneMatch === etag) {
|
|
996
|
+
res.status(import_common9.HttpStatus.NOT_MODIFIED);
|
|
997
|
+
return null;
|
|
998
|
+
}
|
|
999
|
+
return m;
|
|
1000
|
+
}
|
|
1001
|
+
reload() {
|
|
1002
|
+
const m = this.manifest.rebuild();
|
|
1003
|
+
return {
|
|
1004
|
+
manifestHash: m.build.manifestHash,
|
|
1005
|
+
reloadedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
_ts_decorate9([
|
|
1010
|
+
(0, import_common9.Get)("manifest"),
|
|
1011
|
+
(0, import_common9.Header)("Cache-Control", "private, max-age=60, must-revalidate"),
|
|
1012
|
+
_ts_param7(0, (0, import_common9.Headers)("if-none-match")),
|
|
1013
|
+
_ts_param7(1, (0, import_common9.Res)({
|
|
1014
|
+
passthrough: true
|
|
1015
|
+
})),
|
|
1016
|
+
_ts_metadata7("design:type", Function),
|
|
1017
|
+
_ts_metadata7("design:paramtypes", [
|
|
1018
|
+
Object,
|
|
1019
|
+
typeof HttpResponseLike === "undefined" ? Object : HttpResponseLike
|
|
1020
|
+
]),
|
|
1021
|
+
_ts_metadata7("design:returntype", void 0)
|
|
1022
|
+
], GeneratedAdminManifestController.prototype, "getManifest", null);
|
|
1023
|
+
_ts_decorate9([
|
|
1024
|
+
(0, import_common9.Post)("manifest/reload"),
|
|
1025
|
+
(0, import_common9.UseGuards)(...reloadChain),
|
|
1026
|
+
(0, import_common9.HttpCode)(import_common9.HttpStatus.OK),
|
|
1027
|
+
_ts_metadata7("design:type", Function),
|
|
1028
|
+
_ts_metadata7("design:paramtypes", []),
|
|
1029
|
+
_ts_metadata7("design:returntype", void 0)
|
|
1030
|
+
], GeneratedAdminManifestController.prototype, "reload", null);
|
|
1031
|
+
GeneratedAdminManifestController = _ts_decorate9([
|
|
1032
|
+
(0, import_common9.Controller)("admin"),
|
|
1033
|
+
(0, import_common9.UseGuards)(...guards),
|
|
1034
|
+
_ts_param7(0, (0, import_common9.Inject)(AdminManifestService)),
|
|
1035
|
+
_ts_metadata7("design:type", Function),
|
|
1036
|
+
_ts_metadata7("design:paramtypes", [
|
|
1037
|
+
typeof AdminManifestService === "undefined" ? Object : AdminManifestService
|
|
1038
|
+
])
|
|
1039
|
+
], GeneratedAdminManifestController);
|
|
1040
|
+
return GeneratedAdminManifestController;
|
|
1041
|
+
}
|
|
1042
|
+
__name(buildManifestController, "buildManifestController");
|
|
1043
|
+
var AdminManifestModule = class _AdminManifestModule {
|
|
1044
|
+
static {
|
|
1045
|
+
__name(this, "AdminManifestModule");
|
|
1046
|
+
}
|
|
1047
|
+
static forRoot(options) {
|
|
1048
|
+
const includeManifestController = options.includeManifestController ?? true;
|
|
1049
|
+
const registerPlatformCore = options.registerPlatformCore ?? true;
|
|
1050
|
+
const controllers = [
|
|
1051
|
+
AdminPublicBootController
|
|
1052
|
+
];
|
|
1053
|
+
if (includeManifestController) {
|
|
1054
|
+
if (options.guards === void 0) {
|
|
1055
|
+
throw new Error("AdminManifestModule.forRoot: `guards` ist Pflicht, wenn `includeManifestController` aktiv ist (Default `true`). Setze `guards: [JwtAuthGuard, SuperAdminGuard]` (oder analog) \u2014 oder `guards: []`, um den Endpoint absichtlich auth-frei zu betreiben. Alternative: `includeManifestController: false` und einen eigenen Wrapping-Controller registrieren.");
|
|
1056
|
+
}
|
|
1057
|
+
controllers.push(buildManifestController(options.guards, options.reloadGuards ?? []));
|
|
1058
|
+
}
|
|
1059
|
+
const providers = [
|
|
1060
|
+
asConfigProvider(options.config),
|
|
1061
|
+
AdminManifestService,
|
|
1062
|
+
...options.extraProviders ?? []
|
|
1063
|
+
];
|
|
1064
|
+
if (registerPlatformCore) {
|
|
1065
|
+
providers.push({
|
|
1066
|
+
provide: PLATFORM_CORE_CONTRIBUTION_TOKEN,
|
|
1067
|
+
useValue: PLATFORM_CORE_MANIFEST_CONTRIBUTION
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
return {
|
|
1071
|
+
module: _AdminManifestModule,
|
|
1072
|
+
global: options.global ?? false,
|
|
1073
|
+
imports: options.imports ?? [],
|
|
1074
|
+
controllers,
|
|
1075
|
+
providers,
|
|
1076
|
+
exports: [
|
|
1077
|
+
ADMIN_MANIFEST_CONFIG,
|
|
1078
|
+
AdminManifestService
|
|
1079
|
+
]
|
|
1080
|
+
};
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
AdminManifestModule = _ts_decorate9([
|
|
1084
|
+
(0, import_common9.Module)({})
|
|
1085
|
+
], AdminManifestModule);
|
|
1086
|
+
|
|
1087
|
+
// src/admin/admin-stats.tokens.ts
|
|
1088
|
+
var SUBSCRIPTION_STATS_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SubscriptionStatsPort");
|
|
1089
|
+
var PROMO_CODE_STATS_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PromoCodeStatsPort");
|
|
1090
|
+
var AUDIT_STATS_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/AuditStatsPort");
|
|
1091
|
+
var ADMIN_STATS_AUDIT_WINDOW_DAYS_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/AdminStatsAuditWindowDays");
|
|
1092
|
+
|
|
1093
|
+
// src/admin/admin-stats.service.ts
|
|
1094
|
+
var import_common10 = require("@nestjs/common");
|
|
1095
|
+
function _ts_decorate10(decorators, target, key, desc) {
|
|
1096
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1097
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1098
|
+
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;
|
|
1099
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1100
|
+
}
|
|
1101
|
+
__name(_ts_decorate10, "_ts_decorate");
|
|
1102
|
+
function _ts_metadata8(k, v) {
|
|
1103
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1104
|
+
}
|
|
1105
|
+
__name(_ts_metadata8, "_ts_metadata");
|
|
1106
|
+
function _ts_param8(paramIndex, decorator) {
|
|
1107
|
+
return function(target, key) {
|
|
1108
|
+
decorator(target, key, paramIndex);
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1111
|
+
__name(_ts_param8, "_ts_param");
|
|
1112
|
+
var DAY_MS = 864e5;
|
|
1113
|
+
var DEFAULT_AUDIT_WINDOW_DAYS = 7;
|
|
1114
|
+
var AdminStatsService = class {
|
|
1115
|
+
static {
|
|
1116
|
+
__name(this, "AdminStatsService");
|
|
1117
|
+
}
|
|
1118
|
+
subscriptions;
|
|
1119
|
+
promos;
|
|
1120
|
+
audit;
|
|
1121
|
+
auditWindowDays;
|
|
1122
|
+
constructor(subscriptions, promos, audit, auditWindowDays = DEFAULT_AUDIT_WINDOW_DAYS) {
|
|
1123
|
+
this.subscriptions = subscriptions;
|
|
1124
|
+
this.promos = promos;
|
|
1125
|
+
this.audit = audit;
|
|
1126
|
+
this.auditWindowDays = auditWindowDays;
|
|
1127
|
+
}
|
|
1128
|
+
async getSnapshot() {
|
|
1129
|
+
const since = new Date(Date.now() - this.auditWindowDays * DAY_MS);
|
|
1130
|
+
const [subscriptions, promos, auditCount] = await Promise.all([
|
|
1131
|
+
this.subscriptions.getStats(),
|
|
1132
|
+
this.promos.getStats(),
|
|
1133
|
+
this.audit.countSince(since)
|
|
1134
|
+
]);
|
|
1135
|
+
return {
|
|
1136
|
+
subscriptions,
|
|
1137
|
+
promos,
|
|
1138
|
+
audit: {
|
|
1139
|
+
countLastNDays: auditCount,
|
|
1140
|
+
nDays: this.auditWindowDays
|
|
1141
|
+
}
|
|
1142
|
+
};
|
|
1143
|
+
}
|
|
1144
|
+
};
|
|
1145
|
+
AdminStatsService = _ts_decorate10([
|
|
1146
|
+
(0, import_common10.Injectable)(),
|
|
1147
|
+
_ts_param8(0, (0, import_common10.Inject)(SUBSCRIPTION_STATS_PORT_TOKEN)),
|
|
1148
|
+
_ts_param8(1, (0, import_common10.Inject)(PROMO_CODE_STATS_PORT_TOKEN)),
|
|
1149
|
+
_ts_param8(2, (0, import_common10.Inject)(AUDIT_STATS_PORT_TOKEN)),
|
|
1150
|
+
_ts_param8(3, (0, import_common10.Optional)()),
|
|
1151
|
+
_ts_param8(3, (0, import_common10.Inject)(ADMIN_STATS_AUDIT_WINDOW_DAYS_TOKEN)),
|
|
1152
|
+
_ts_metadata8("design:type", Function),
|
|
1153
|
+
_ts_metadata8("design:paramtypes", [
|
|
1154
|
+
typeof SubscriptionStatsPort === "undefined" ? Object : SubscriptionStatsPort,
|
|
1155
|
+
typeof PromoCodeStatsPort === "undefined" ? Object : PromoCodeStatsPort,
|
|
1156
|
+
typeof AuditStatsPort === "undefined" ? Object : AuditStatsPort,
|
|
1157
|
+
Number
|
|
1158
|
+
])
|
|
1159
|
+
], AdminStatsService);
|
|
1160
|
+
|
|
1161
|
+
// src/admin/admin-stats.controller.ts
|
|
1162
|
+
var import_common11 = require("@nestjs/common");
|
|
1163
|
+
function _ts_decorate11(decorators, target, key, desc) {
|
|
1164
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1165
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1166
|
+
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;
|
|
1167
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1168
|
+
}
|
|
1169
|
+
__name(_ts_decorate11, "_ts_decorate");
|
|
1170
|
+
function _ts_metadata9(k, v) {
|
|
1171
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1172
|
+
}
|
|
1173
|
+
__name(_ts_metadata9, "_ts_metadata");
|
|
1174
|
+
function _ts_param9(paramIndex, decorator) {
|
|
1175
|
+
return function(target, key) {
|
|
1176
|
+
decorator(target, key, paramIndex);
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
__name(_ts_param9, "_ts_param");
|
|
1180
|
+
var AdminStatsController = class {
|
|
1181
|
+
static {
|
|
1182
|
+
__name(this, "AdminStatsController");
|
|
1183
|
+
}
|
|
1184
|
+
stats;
|
|
1185
|
+
// Explicit @Inject instead of type reflection: tsup/esbuild do not emit
|
|
1186
|
+
// `design:paramtypes` metadata, so Nest could otherwise not resolve the
|
|
1187
|
+
// service type at the constructor.
|
|
1188
|
+
constructor(stats) {
|
|
1189
|
+
this.stats = stats;
|
|
1190
|
+
}
|
|
1191
|
+
async getDashboardSnapshot() {
|
|
1192
|
+
return this.stats.getSnapshot();
|
|
1193
|
+
}
|
|
1194
|
+
};
|
|
1195
|
+
_ts_decorate11([
|
|
1196
|
+
(0, import_common11.Get)("dashboard"),
|
|
1197
|
+
_ts_metadata9("design:type", Function),
|
|
1198
|
+
_ts_metadata9("design:paramtypes", []),
|
|
1199
|
+
_ts_metadata9("design:returntype", Promise)
|
|
1200
|
+
], AdminStatsController.prototype, "getDashboardSnapshot", null);
|
|
1201
|
+
AdminStatsController = _ts_decorate11([
|
|
1202
|
+
(0, import_common11.Controller)("admin/stats"),
|
|
1203
|
+
(0, import_common11.UseGuards)(SuperAdminGuard),
|
|
1204
|
+
_ts_param9(0, (0, import_common11.Inject)(AdminStatsService)),
|
|
1205
|
+
_ts_metadata9("design:type", Function),
|
|
1206
|
+
_ts_metadata9("design:paramtypes", [
|
|
1207
|
+
typeof AdminStatsService === "undefined" ? Object : AdminStatsService
|
|
1208
|
+
])
|
|
1209
|
+
], AdminStatsController);
|
|
1210
|
+
|
|
1211
|
+
// src/admin/admin-stats.module.ts
|
|
1212
|
+
var import_common12 = require("@nestjs/common");
|
|
1213
|
+
function _ts_decorate12(decorators, target, key, desc) {
|
|
1214
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1215
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1216
|
+
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;
|
|
1217
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1218
|
+
}
|
|
1219
|
+
__name(_ts_decorate12, "_ts_decorate");
|
|
1220
|
+
var AdminStatsModule = class _AdminStatsModule {
|
|
1221
|
+
static {
|
|
1222
|
+
__name(this, "AdminStatsModule");
|
|
1223
|
+
}
|
|
1224
|
+
static forRoot(options) {
|
|
1225
|
+
const providers = [
|
|
1226
|
+
asProvider(SUBSCRIPTION_STATS_PORT_TOKEN, options.subscriptionStatsPort),
|
|
1227
|
+
asProvider(PROMO_CODE_STATS_PORT_TOKEN, options.promoCodeStatsPort),
|
|
1228
|
+
asProvider(AUDIT_STATS_PORT_TOKEN, options.auditStatsPort),
|
|
1229
|
+
AdminStatsService,
|
|
1230
|
+
SuperAdminGuard
|
|
1231
|
+
];
|
|
1232
|
+
if (options.auditWindowDays !== void 0) {
|
|
1233
|
+
providers.push({
|
|
1234
|
+
provide: ADMIN_STATS_AUDIT_WINDOW_DAYS_TOKEN,
|
|
1235
|
+
useValue: options.auditWindowDays
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
if (options.extraProviders) providers.push(...options.extraProviders);
|
|
1239
|
+
return {
|
|
1240
|
+
module: _AdminStatsModule,
|
|
1241
|
+
global: options.global ?? false,
|
|
1242
|
+
imports: options.imports ?? [],
|
|
1243
|
+
controllers: [
|
|
1244
|
+
AdminStatsController
|
|
1245
|
+
],
|
|
1246
|
+
providers,
|
|
1247
|
+
exports: [
|
|
1248
|
+
AdminStatsService,
|
|
1249
|
+
SuperAdminGuard
|
|
1250
|
+
]
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
AdminStatsModule = _ts_decorate12([
|
|
1255
|
+
(0, import_common12.Module)({})
|
|
1256
|
+
], AdminStatsModule);
|
|
1257
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1258
|
+
0 && (module.exports = {
|
|
1259
|
+
ADMIN_MANIFEST_CONFIG,
|
|
1260
|
+
ADMIN_STATS_AUDIT_WINDOW_DAYS_TOKEN,
|
|
1261
|
+
AUDIT_PORT_TOKEN,
|
|
1262
|
+
AUDIT_STATS_PORT_TOKEN,
|
|
1263
|
+
AdminAuditService,
|
|
1264
|
+
AdminBypassRlsInterceptor,
|
|
1265
|
+
AdminManifestModule,
|
|
1266
|
+
AdminManifestService,
|
|
1267
|
+
AdminModule,
|
|
1268
|
+
AdminPublicBootController,
|
|
1269
|
+
AdminStatsController,
|
|
1270
|
+
AdminStatsModule,
|
|
1271
|
+
AdminStatsService,
|
|
1272
|
+
MFA_PORT_TOKEN,
|
|
1273
|
+
MfaGuard,
|
|
1274
|
+
MfaService,
|
|
1275
|
+
PLATFORM_CORE_CONTRIBUTION_TOKEN,
|
|
1276
|
+
PLATFORM_CORE_MANIFEST_CONTRIBUTION,
|
|
1277
|
+
PROMO_CODE_STATS_PORT_TOKEN,
|
|
1278
|
+
REQUIRE_MFA_KEY,
|
|
1279
|
+
RLS_BYPASS_PORT_TOKEN,
|
|
1280
|
+
RequireMfa,
|
|
1281
|
+
SUBSCRIPTION_STATS_PORT_TOKEN,
|
|
1282
|
+
SuperAdminGuard
|
|
1283
|
+
});
|