@dudousxd/nestjs-media-dashboard 0.1.2 → 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.
@@ -5,14 +5,256 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
5
5
  import { Module as Module2 } from "@nestjs/common";
6
6
  import { RouterModule } from "@nestjs/core";
7
7
 
8
+ // src/server/auth/config.ts
9
+ var DEFAULT_TTL_MS = 8 * 60 * 60 * 1e3;
10
+ var DURATION_UNITS = {
11
+ s: 1e3,
12
+ m: 60 * 1e3,
13
+ h: 60 * 60 * 1e3,
14
+ d: 24 * 60 * 60 * 1e3
15
+ };
16
+ function durationToMs(ttl) {
17
+ if (ttl === void 0) return DEFAULT_TTL_MS;
18
+ const match = /^(\d+)([smhd])$/.exec(ttl.trim());
19
+ if (!match) return DEFAULT_TTL_MS;
20
+ const unit = DURATION_UNITS[match[2] ?? ""];
21
+ if (unit === void 0) return DEFAULT_TTL_MS;
22
+ return Number(match[1]) * unit;
23
+ }
24
+ __name(durationToMs, "durationToMs");
25
+ function resolveConsoleAuth(options) {
26
+ if (!options) return null;
27
+ if (!options.secret) {
28
+ throw new Error("MediaDashboardModule: auth.secret is required when `auth` is configured.");
29
+ }
30
+ const modes = [];
31
+ if (options.session) modes.push("session");
32
+ if (options.login) modes.push("login");
33
+ if (modes.length === 0) {
34
+ throw new Error("MediaDashboardModule: auth needs a `login` and/or `session` hook.");
35
+ }
36
+ return {
37
+ secret: options.secret,
38
+ ttlMs: durationToMs(options.ttl),
39
+ modes,
40
+ ...options.session ? {
41
+ session: options.session
42
+ } : {},
43
+ ...options.login ? {
44
+ login: options.login
45
+ } : {}
46
+ };
47
+ }
48
+ __name(resolveConsoleAuth, "resolveConsoleAuth");
49
+
8
50
  // src/server/media-console-api.module.ts
9
51
  import { Module } from "@nestjs/common";
10
52
 
11
53
  // src/server/media-console-actions.controller.ts
12
- import { Body, Controller, Delete, HttpCode, Inject as Inject2, Param, Post, Query, Req } from "@nestjs/common";
54
+ import { Body, Controller, Delete, HttpCode, Inject as Inject3, Param, Post, Query, Req, UseGuards } from "@nestjs/common";
13
55
 
14
- // src/server/media-console.service.ts
15
- import { BadRequestException, Inject, Injectable, NotFoundException, Optional } from "@nestjs/common";
56
+ // src/server/media-console.guard.ts
57
+ import { Inject, Injectable, Optional, UnauthorizedException } from "@nestjs/common";
58
+
59
+ // src/server/auth/cookie-header.ts
60
+ function parseCookieHeader(header) {
61
+ const cookies = {};
62
+ if (typeof header !== "string" || header === "") return cookies;
63
+ for (const segment of header.split(";")) {
64
+ const eq = segment.indexOf("=");
65
+ if (eq <= 0) continue;
66
+ const name = segment.slice(0, eq).trim();
67
+ if (name === "") continue;
68
+ let rawValue = segment.slice(eq + 1).trim();
69
+ if (rawValue.length >= 2 && rawValue.startsWith('"') && rawValue.endsWith('"')) {
70
+ rawValue = rawValue.slice(1, -1);
71
+ }
72
+ if (name in cookies) continue;
73
+ try {
74
+ cookies[name] = decodeURIComponent(rawValue);
75
+ } catch {
76
+ cookies[name] = rawValue;
77
+ }
78
+ }
79
+ return cookies;
80
+ }
81
+ __name(parseCookieHeader, "parseCookieHeader");
82
+ function serializeSetCookie(name, value, options) {
83
+ const parts = [
84
+ `${name}=${options.clear ? "" : encodeURIComponent(value)}`
85
+ ];
86
+ parts.push(`Path=${options.path}`);
87
+ parts.push("HttpOnly");
88
+ parts.push("SameSite=Lax");
89
+ if (options.secure) parts.push("Secure");
90
+ if (options.clear) {
91
+ parts.push("Max-Age=0");
92
+ parts.push("Expires=Thu, 01 Jan 1970 00:00:00 GMT");
93
+ } else {
94
+ parts.push(`Max-Age=${options.maxAgeSeconds}`);
95
+ }
96
+ return parts.join("; ");
97
+ }
98
+ __name(serializeSetCookie, "serializeSetCookie");
99
+
100
+ // src/server/auth/request.ts
101
+ function isRecord(value) {
102
+ return typeof value === "object" && value !== null;
103
+ }
104
+ __name(isRecord, "isRecord");
105
+ function readHeaders(request) {
106
+ if (!isRecord(request)) return {};
107
+ const headers = request.headers;
108
+ return isRecord(headers) ? headers : {};
109
+ }
110
+ __name(readHeaders, "readHeaders");
111
+ function headerToString(value) {
112
+ if (typeof value === "string") return value;
113
+ if (Array.isArray(value) && value.every((part) => typeof part === "string")) {
114
+ return value.join(",");
115
+ }
116
+ return void 0;
117
+ }
118
+ __name(headerToString, "headerToString");
119
+ function readCookieHeader(request) {
120
+ return headerToString(readHeaders(request).cookie);
121
+ }
122
+ __name(readCookieHeader, "readCookieHeader");
123
+ function isHttpsRequest(request) {
124
+ if (isRecord(request) && request.protocol === "https") return true;
125
+ const forwarded = headerToString(readHeaders(request)["x-forwarded-proto"]);
126
+ if (forwarded === void 0) return false;
127
+ return forwarded.split(",").map((proto) => proto.trim().toLowerCase()).includes("https");
128
+ }
129
+ __name(isHttpsRequest, "isHttpsRequest");
130
+ function attachSession(request, session) {
131
+ if (!isRecord(request)) return;
132
+ request.consoleSession = session;
133
+ }
134
+ __name(attachSession, "attachSession");
135
+
136
+ // src/server/auth/response.ts
137
+ function isRecord2(value) {
138
+ return typeof value === "object" && value !== null;
139
+ }
140
+ __name(isRecord2, "isRecord");
141
+ function isRawNodeResponse(value) {
142
+ return isRecord2(value) && typeof value.getHeader === "function" && typeof value.setHeader === "function";
143
+ }
144
+ __name(isRawNodeResponse, "isRawNodeResponse");
145
+ function resolveRawResponse(response) {
146
+ if (isRawNodeResponse(response)) return response;
147
+ if (isRecord2(response) && isRawNodeResponse(response.raw)) return response.raw;
148
+ return null;
149
+ }
150
+ __name(resolveRawResponse, "resolveRawResponse");
151
+ function existingSetCookies(response) {
152
+ const current = response.getHeader("set-cookie");
153
+ if (Array.isArray(current)) return current;
154
+ if (typeof current === "string") return [
155
+ current
156
+ ];
157
+ return [];
158
+ }
159
+ __name(existingSetCookies, "existingSetCookies");
160
+ function appendSetCookie(response, cookie) {
161
+ const raw = resolveRawResponse(response);
162
+ if (!raw) return;
163
+ raw.setHeader("set-cookie", [
164
+ ...existingSetCookies(raw),
165
+ cookie
166
+ ]);
167
+ }
168
+ __name(appendSetCookie, "appendSetCookie");
169
+
170
+ // src/server/auth/session-cookie.ts
171
+ import { createHmac, timingSafeEqual } from "node:crypto";
172
+ var EXP_GRACE_MS = 3e4;
173
+ function base64urlEncode(value) {
174
+ return Buffer.from(value, "utf8").toString("base64url");
175
+ }
176
+ __name(base64urlEncode, "base64urlEncode");
177
+ function base64urlDecode(value) {
178
+ return Buffer.from(value, "base64url").toString("utf8");
179
+ }
180
+ __name(base64urlDecode, "base64urlDecode");
181
+ function hmac(secret, payload) {
182
+ return createHmac("sha256", secret).update(payload).digest("base64url");
183
+ }
184
+ __name(hmac, "hmac");
185
+ function signSessionCookie(user, options) {
186
+ const issuedAt = options.now ?? Date.now();
187
+ const session = {
188
+ sub: user.id,
189
+ ...user.name !== void 0 ? {
190
+ name: user.name
191
+ } : {},
192
+ roles: user.roles ?? [],
193
+ iat: issuedAt,
194
+ exp: issuedAt + options.ttlMs
195
+ };
196
+ const encodedPayload = base64urlEncode(JSON.stringify(session));
197
+ return `${encodedPayload}.${hmac(options.secret, encodedPayload)}`;
198
+ }
199
+ __name(signSessionCookie, "signSessionCookie");
200
+ function isSessionPayload(value) {
201
+ if (typeof value !== "object" || value === null) return false;
202
+ const record = value;
203
+ if (typeof record.sub !== "string") return false;
204
+ if (record.name !== void 0 && typeof record.name !== "string") return false;
205
+ if (!Array.isArray(record.roles)) return false;
206
+ if (!record.roles.every((role) => typeof role === "string")) return false;
207
+ if (typeof record.iat !== "number" || !Number.isFinite(record.iat)) return false;
208
+ if (typeof record.exp !== "number" || !Number.isFinite(record.exp)) return false;
209
+ return true;
210
+ }
211
+ __name(isSessionPayload, "isSessionPayload");
212
+ function verifySessionCookie(value, options) {
213
+ try {
214
+ const dot = value.indexOf(".");
215
+ if (dot <= 0 || dot === value.length - 1) return null;
216
+ const encodedPayload = value.slice(0, dot);
217
+ const provided = Buffer.from(value.slice(dot + 1), "base64url");
218
+ const expected = Buffer.from(hmac(options.secret, encodedPayload), "base64url");
219
+ if (provided.length !== expected.length) return null;
220
+ if (!timingSafeEqual(provided, expected)) return null;
221
+ const decoded = JSON.parse(base64urlDecode(encodedPayload));
222
+ if (!isSessionPayload(decoded)) return null;
223
+ const now = options.now ?? Date.now();
224
+ if (now > decoded.exp + EXP_GRACE_MS) return null;
225
+ return decoded;
226
+ } catch {
227
+ return null;
228
+ }
229
+ }
230
+ __name(verifySessionCookie, "verifySessionCookie");
231
+
232
+ // src/server/auth/session-cookie-io.ts
233
+ var SESSION_COOKIE_NAME = "media_console_session";
234
+ function issueSessionCookie(user, context) {
235
+ const value = signSessionCookie(user, {
236
+ secret: context.auth.secret,
237
+ ttlMs: context.auth.ttlMs,
238
+ ...context.now !== void 0 ? {
239
+ now: context.now
240
+ } : {}
241
+ });
242
+ appendSetCookie(context.response, serializeSetCookie(SESSION_COOKIE_NAME, value, {
243
+ path: context.cookiePath,
244
+ maxAgeSeconds: Math.floor(context.auth.ttlMs / 1e3),
245
+ secure: isHttpsRequest(context.request)
246
+ }));
247
+ }
248
+ __name(issueSessionCookie, "issueSessionCookie");
249
+ function clearSessionCookie(context) {
250
+ appendSetCookie(context.response, serializeSetCookie(SESSION_COOKIE_NAME, "", {
251
+ path: context.cookiePath,
252
+ maxAgeSeconds: 0,
253
+ secure: isHttpsRequest(context.request),
254
+ clear: true
255
+ }));
256
+ }
257
+ __name(clearSessionCookie, "clearSessionCookie");
16
258
 
17
259
  // src/server/tokens.ts
18
260
  var MEDIA_STORE = Symbol.for("nestjs-media:store");
@@ -21,8 +263,10 @@ var MEDIA_STORAGE_SHARED = Symbol.for("nestjs-media:storage");
21
263
  var MEDIA_DASHBOARD_BASE_PATH = Symbol("MEDIA_DASHBOARD_BASE_PATH");
22
264
  var MEDIA_DASHBOARD_API_PATH = Symbol("MEDIA_DASHBOARD_API_PATH");
23
265
  var MEDIA_DASHBOARD_ACTIONS = Symbol("MEDIA_DASHBOARD_ACTIONS");
266
+ var MEDIA_CONSOLE_AUTH = Symbol("MEDIA_CONSOLE_AUTH");
267
+ var MEDIA_CONSOLE_COOKIE_PATH = Symbol("MEDIA_CONSOLE_COOKIE_PATH");
24
268
 
25
- // src/server/media-console.service.ts
269
+ // src/server/media-console.guard.ts
26
270
  function _ts_decorate(decorators, target, key, desc) {
27
271
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
28
272
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -40,6 +284,89 @@ function _ts_param(paramIndex, decorator) {
40
284
  };
41
285
  }
42
286
  __name(_ts_param, "_ts_param");
287
+ var MediaConsoleGuard = class {
288
+ static {
289
+ __name(this, "MediaConsoleGuard");
290
+ }
291
+ auth;
292
+ cookiePath;
293
+ constructor(auth, cookiePath) {
294
+ this.auth = auth;
295
+ this.cookiePath = cookiePath;
296
+ }
297
+ canActivate(context) {
298
+ if (!this.auth) return true;
299
+ const http = context.switchToHttp();
300
+ const request = http.getRequest();
301
+ const session = this.verifyRequestSession(request);
302
+ if (!session) throw new UnauthorizedException();
303
+ attachSession(request, session);
304
+ this.maybeRenew(http.getResponse(), request, session);
305
+ return true;
306
+ }
307
+ verifyRequestSession(request) {
308
+ if (!this.auth) return null;
309
+ const cookieValue = parseCookieHeader(readCookieHeader(request))[SESSION_COOKIE_NAME];
310
+ if (cookieValue === void 0) return null;
311
+ return verifySessionCookie(cookieValue, {
312
+ secret: this.auth.secret
313
+ });
314
+ }
315
+ /**
316
+ * Sliding renewal: when a valid cookie is past half its TTL, re-issue a fresh one so active users
317
+ * never get logged out mid-session. Appends a new Set-Cookie (preserving any others already set).
318
+ */
319
+ maybeRenew(response, request, session) {
320
+ if (!this.auth) return;
321
+ const now = Date.now();
322
+ if (now - session.iat <= this.auth.ttlMs / 2) return;
323
+ issueSessionCookie({
324
+ id: session.sub,
325
+ ...session.name !== void 0 ? {
326
+ name: session.name
327
+ } : {},
328
+ roles: session.roles
329
+ }, {
330
+ auth: this.auth,
331
+ cookiePath: this.cookiePath ?? "/",
332
+ request,
333
+ response,
334
+ now
335
+ });
336
+ }
337
+ };
338
+ MediaConsoleGuard = _ts_decorate([
339
+ Injectable(),
340
+ _ts_param(0, Optional()),
341
+ _ts_param(0, Inject(MEDIA_CONSOLE_AUTH)),
342
+ _ts_param(1, Optional()),
343
+ _ts_param(1, Inject(MEDIA_CONSOLE_COOKIE_PATH)),
344
+ _ts_metadata("design:type", Function),
345
+ _ts_metadata("design:paramtypes", [
346
+ Object,
347
+ Object
348
+ ])
349
+ ], MediaConsoleGuard);
350
+
351
+ // src/server/media-console.service.ts
352
+ import { BadRequestException, Inject as Inject2, Injectable as Injectable2, NotFoundException, Optional as Optional2 } from "@nestjs/common";
353
+ function _ts_decorate2(decorators, target, key, desc) {
354
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
355
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
356
+ 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;
357
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
358
+ }
359
+ __name(_ts_decorate2, "_ts_decorate");
360
+ function _ts_metadata2(k, v) {
361
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
362
+ }
363
+ __name(_ts_metadata2, "_ts_metadata");
364
+ function _ts_param2(paramIndex, decorator) {
365
+ return function(target, key) {
366
+ decorator(target, key, paramIndex);
367
+ };
368
+ }
369
+ __name(_ts_param2, "_ts_param");
43
370
  var URL_TTL_SECONDS = 300;
44
371
  var DEFAULT_PAGE_LIMIT = 50;
45
372
  function lastSegment(prefix) {
@@ -301,18 +628,18 @@ var MediaConsoleService = class {
301
628
  };
302
629
  }
303
630
  };
304
- MediaConsoleService = _ts_decorate([
305
- Injectable(),
306
- _ts_param(0, Optional()),
307
- _ts_param(0, Inject(MEDIA_STORAGE_SHARED)),
308
- _ts_param(1, Optional()),
309
- _ts_param(1, Inject(MEDIA_STORE)),
310
- _ts_param(2, Optional()),
311
- _ts_param(2, Inject(MEDIA_UPLOAD_SESSIONS)),
312
- _ts_param(3, Optional()),
313
- _ts_param(3, Inject(MEDIA_DASHBOARD_ACTIONS)),
314
- _ts_metadata("design:type", Function),
315
- _ts_metadata("design:paramtypes", [
631
+ MediaConsoleService = _ts_decorate2([
632
+ Injectable2(),
633
+ _ts_param2(0, Optional2()),
634
+ _ts_param2(0, Inject2(MEDIA_STORAGE_SHARED)),
635
+ _ts_param2(1, Optional2()),
636
+ _ts_param2(1, Inject2(MEDIA_STORE)),
637
+ _ts_param2(2, Optional2()),
638
+ _ts_param2(2, Inject2(MEDIA_UPLOAD_SESSIONS)),
639
+ _ts_param2(3, Optional2()),
640
+ _ts_param2(3, Inject2(MEDIA_DASHBOARD_ACTIONS)),
641
+ _ts_metadata2("design:type", Function),
642
+ _ts_metadata2("design:paramtypes", [
316
643
  Object,
317
644
  Object,
318
645
  Object,
@@ -321,23 +648,23 @@ MediaConsoleService = _ts_decorate([
321
648
  ], MediaConsoleService);
322
649
 
323
650
  // src/server/media-console-actions.controller.ts
324
- function _ts_decorate2(decorators, target, key, desc) {
651
+ function _ts_decorate3(decorators, target, key, desc) {
325
652
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
326
653
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
327
654
  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;
328
655
  return c > 3 && r && Object.defineProperty(target, key, r), r;
329
656
  }
330
- __name(_ts_decorate2, "_ts_decorate");
331
- function _ts_metadata2(k, v) {
657
+ __name(_ts_decorate3, "_ts_decorate");
658
+ function _ts_metadata3(k, v) {
332
659
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
333
660
  }
334
- __name(_ts_metadata2, "_ts_metadata");
335
- function _ts_param2(paramIndex, decorator) {
661
+ __name(_ts_metadata3, "_ts_metadata");
662
+ function _ts_param3(paramIndex, decorator) {
336
663
  return function(target, key) {
337
664
  decorator(target, key, paramIndex);
338
665
  };
339
666
  }
340
- __name(_ts_param2, "_ts_param");
667
+ __name(_ts_param3, "_ts_param");
341
668
  var MediaConsoleActionsController = class {
342
669
  static {
343
670
  __name(this, "MediaConsoleActionsController");
@@ -373,118 +700,303 @@ var MediaConsoleActionsController = class {
373
700
  return this.service.deleteLibraryRecord(id);
374
701
  }
375
702
  };
376
- _ts_decorate2([
703
+ _ts_decorate3([
377
704
  Delete("disks/:disk/object"),
378
705
  HttpCode(204),
379
- _ts_param2(0, Param("disk")),
380
- _ts_param2(1, Query("key")),
381
- _ts_metadata2("design:type", Function),
382
- _ts_metadata2("design:paramtypes", [
706
+ _ts_param3(0, Param("disk")),
707
+ _ts_param3(1, Query("key")),
708
+ _ts_metadata3("design:type", Function),
709
+ _ts_metadata3("design:paramtypes", [
383
710
  String,
384
711
  String
385
712
  ]),
386
- _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
713
+ _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
387
714
  ], MediaConsoleActionsController.prototype, "deleteObject", null);
388
- _ts_decorate2([
715
+ _ts_decorate3([
389
716
  Post("disks/:disk/copy"),
390
717
  HttpCode(204),
391
- _ts_param2(0, Param("disk")),
392
- _ts_param2(1, Body()),
393
- _ts_metadata2("design:type", Function),
394
- _ts_metadata2("design:paramtypes", [
718
+ _ts_param3(0, Param("disk")),
719
+ _ts_param3(1, Body()),
720
+ _ts_metadata3("design:type", Function),
721
+ _ts_metadata3("design:paramtypes", [
395
722
  String,
396
723
  typeof CopyMoveBody === "undefined" ? Object : CopyMoveBody
397
724
  ]),
398
- _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
725
+ _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
399
726
  ], MediaConsoleActionsController.prototype, "copyObject", null);
400
- _ts_decorate2([
727
+ _ts_decorate3([
401
728
  Post("disks/:disk/move"),
402
729
  HttpCode(204),
403
- _ts_param2(0, Param("disk")),
404
- _ts_param2(1, Body()),
405
- _ts_metadata2("design:type", Function),
406
- _ts_metadata2("design:paramtypes", [
730
+ _ts_param3(0, Param("disk")),
731
+ _ts_param3(1, Body()),
732
+ _ts_metadata3("design:type", Function),
733
+ _ts_metadata3("design:paramtypes", [
407
734
  String,
408
735
  typeof CopyMoveBody === "undefined" ? Object : CopyMoveBody
409
736
  ]),
410
- _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
737
+ _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
411
738
  ], MediaConsoleActionsController.prototype, "moveObject", null);
412
- _ts_decorate2([
739
+ _ts_decorate3([
413
740
  Post("disks/:disk/upload"),
414
741
  HttpCode(204),
415
- _ts_param2(0, Param("disk")),
416
- _ts_param2(1, Query("key")),
417
- _ts_param2(2, Req()),
418
- _ts_param2(3, Query("type")),
419
- _ts_metadata2("design:type", Function),
420
- _ts_metadata2("design:paramtypes", [
742
+ _ts_param3(0, Param("disk")),
743
+ _ts_param3(1, Query("key")),
744
+ _ts_param3(2, Req()),
745
+ _ts_param3(3, Query("type")),
746
+ _ts_metadata3("design:type", Function),
747
+ _ts_metadata3("design:paramtypes", [
421
748
  String,
422
749
  String,
423
750
  typeof Readable === "undefined" ? Object : Readable,
424
751
  String
425
752
  ]),
426
- _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
753
+ _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
427
754
  ], MediaConsoleActionsController.prototype, "uploadObject", null);
428
- _ts_decorate2([
755
+ _ts_decorate3([
429
756
  Post("disks/:disk/folder"),
430
757
  HttpCode(204),
431
- _ts_param2(0, Param("disk")),
432
- _ts_param2(1, Body()),
433
- _ts_metadata2("design:type", Function),
434
- _ts_metadata2("design:paramtypes", [
758
+ _ts_param3(0, Param("disk")),
759
+ _ts_param3(1, Body()),
760
+ _ts_metadata3("design:type", Function),
761
+ _ts_metadata3("design:paramtypes", [
435
762
  String,
436
763
  typeof CreateFolderBody === "undefined" ? Object : CreateFolderBody
437
764
  ]),
438
- _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
765
+ _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
439
766
  ], MediaConsoleActionsController.prototype, "createFolder", null);
440
- _ts_decorate2([
767
+ _ts_decorate3([
441
768
  Post("uploads/:id/abort"),
442
769
  HttpCode(204),
443
- _ts_param2(0, Param("id")),
444
- _ts_metadata2("design:type", Function),
445
- _ts_metadata2("design:paramtypes", [
770
+ _ts_param3(0, Param("id")),
771
+ _ts_metadata3("design:type", Function),
772
+ _ts_metadata3("design:paramtypes", [
446
773
  String
447
774
  ]),
448
- _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
775
+ _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
449
776
  ], MediaConsoleActionsController.prototype, "abortUpload", null);
450
- _ts_decorate2([
777
+ _ts_decorate3([
451
778
  Delete("library/:id"),
452
779
  HttpCode(204),
453
- _ts_param2(0, Param("id")),
454
- _ts_metadata2("design:type", Function),
455
- _ts_metadata2("design:paramtypes", [
780
+ _ts_param3(0, Param("id")),
781
+ _ts_metadata3("design:type", Function),
782
+ _ts_metadata3("design:paramtypes", [
456
783
  String
457
784
  ]),
458
- _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
785
+ _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
459
786
  ], MediaConsoleActionsController.prototype, "deleteLibraryRecord", null);
460
- MediaConsoleActionsController = _ts_decorate2([
787
+ MediaConsoleActionsController = _ts_decorate3([
788
+ UseGuards(MediaConsoleGuard),
461
789
  Controller(),
462
- _ts_param2(0, Inject2(MediaConsoleService)),
463
- _ts_metadata2("design:type", Function),
464
- _ts_metadata2("design:paramtypes", [
790
+ _ts_param3(0, Inject3(MediaConsoleService)),
791
+ _ts_metadata3("design:type", Function),
792
+ _ts_metadata3("design:paramtypes", [
465
793
  typeof MediaConsoleService === "undefined" ? Object : MediaConsoleService
466
794
  ])
467
795
  ], MediaConsoleActionsController);
468
796
 
797
+ // src/server/media-console-auth.controller.ts
798
+ import { BadRequestException as BadRequestException2, Body as Body2, Controller as Controller2, Get, HttpCode as HttpCode2, Inject as Inject4, Logger, NotFoundException as NotFoundException2, Optional as Optional3, Post as Post2, Req as Req2, Res, UnauthorizedException as UnauthorizedException2 } from "@nestjs/common";
799
+ function _ts_decorate4(decorators, target, key, desc) {
800
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
801
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
802
+ 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;
803
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
804
+ }
805
+ __name(_ts_decorate4, "_ts_decorate");
806
+ function _ts_metadata4(k, v) {
807
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
808
+ }
809
+ __name(_ts_metadata4, "_ts_metadata");
810
+ function _ts_param4(paramIndex, decorator) {
811
+ return function(target, key) {
812
+ decorator(target, key, paramIndex);
813
+ };
814
+ }
815
+ __name(_ts_param4, "_ts_param");
816
+ var MediaConsoleAuthController = class _MediaConsoleAuthController {
817
+ static {
818
+ __name(this, "MediaConsoleAuthController");
819
+ }
820
+ auth;
821
+ cookiePath;
822
+ logger = new Logger(_MediaConsoleAuthController.name);
823
+ /** One warn per hook kind, so a flaky hook doesn't spam logs every request. */
824
+ warnedHooks = /* @__PURE__ */ new Set();
825
+ constructor(auth, cookiePath) {
826
+ this.auth = auth;
827
+ this.cookiePath = cookiePath;
828
+ }
829
+ me(request) {
830
+ if (!this.auth) return {
831
+ authRequired: false
832
+ };
833
+ const cookieValue = parseCookieHeader(readCookieHeader(request))[SESSION_COOKIE_NAME];
834
+ const session = cookieValue !== void 0 ? verifySessionCookie(cookieValue, {
835
+ secret: this.auth.secret
836
+ }) : null;
837
+ if (!session) throw new UnauthorizedException2({
838
+ auth: {
839
+ modes: this.auth.modes
840
+ }
841
+ });
842
+ return {
843
+ user: {
844
+ id: session.sub,
845
+ ...session.name !== void 0 ? {
846
+ name: session.name
847
+ } : {},
848
+ roles: session.roles
849
+ }
850
+ };
851
+ }
852
+ async login(body, request, response) {
853
+ const auth = this.requireAuth();
854
+ if (!auth.login) throw new NotFoundException2();
855
+ if (typeof body?.username !== "string" || typeof body?.password !== "string") {
856
+ throw new BadRequestException2("Body must include string `username` and `password`.");
857
+ }
858
+ const username = body.username;
859
+ const password = body.password;
860
+ const user = await this.runHook("login", () => auth.login?.(username, password) ?? null);
861
+ if (!user) throw new UnauthorizedException2({
862
+ message: "Invalid credentials"
863
+ });
864
+ return this.mint(user, request, response);
865
+ }
866
+ async session(request, response) {
867
+ const auth = this.requireAuth();
868
+ if (!auth.session) throw new NotFoundException2();
869
+ const user = await this.runHook("session", () => auth.session?.(request) ?? null);
870
+ if (!user) throw new UnauthorizedException2();
871
+ return this.mint(user, request, response);
872
+ }
873
+ logout(request, response) {
874
+ clearSessionCookie({
875
+ cookiePath: this.cookiePath ?? "/",
876
+ request,
877
+ response
878
+ });
879
+ }
880
+ requireAuth() {
881
+ if (!this.auth) throw new NotFoundException2();
882
+ return this.auth;
883
+ }
884
+ mint(user, request, response) {
885
+ const auth = this.requireAuth();
886
+ issueSessionCookie(user, {
887
+ auth,
888
+ cookiePath: this.cookiePath ?? "/",
889
+ request,
890
+ response
891
+ });
892
+ return {
893
+ user: {
894
+ id: user.id,
895
+ ...user.name !== void 0 ? {
896
+ name: user.name
897
+ } : {},
898
+ roles: user.roles ?? []
899
+ }
900
+ };
901
+ }
902
+ /** Run a host hook defensively: a throw is a denial (null), warn-logged once per kind. */
903
+ async runHook(kind, run) {
904
+ try {
905
+ return await run() ?? null;
906
+ } catch (error) {
907
+ if (!this.warnedHooks.has(kind)) {
908
+ this.warnedHooks.add(kind);
909
+ this.logger.warn(`Console auth ${kind} hook threw; treating as denial. ${String(error)}`);
910
+ }
911
+ return null;
912
+ }
913
+ }
914
+ };
915
+ _ts_decorate4([
916
+ Get("me"),
917
+ _ts_param4(0, Req2()),
918
+ _ts_metadata4("design:type", Function),
919
+ _ts_metadata4("design:paramtypes", [
920
+ Object
921
+ ]),
922
+ _ts_metadata4("design:returntype", typeof MeResponse === "undefined" ? Object : MeResponse)
923
+ ], MediaConsoleAuthController.prototype, "me", null);
924
+ _ts_decorate4([
925
+ Post2("login"),
926
+ HttpCode2(200),
927
+ _ts_param4(0, Body2()),
928
+ _ts_param4(1, Req2()),
929
+ _ts_param4(2, Res({
930
+ passthrough: true
931
+ })),
932
+ _ts_metadata4("design:type", Function),
933
+ _ts_metadata4("design:paramtypes", [
934
+ typeof LoginBody === "undefined" ? Object : LoginBody,
935
+ Object,
936
+ Object
937
+ ]),
938
+ _ts_metadata4("design:returntype", Promise)
939
+ ], MediaConsoleAuthController.prototype, "login", null);
940
+ _ts_decorate4([
941
+ Post2("session"),
942
+ HttpCode2(200),
943
+ _ts_param4(0, Req2()),
944
+ _ts_param4(1, Res({
945
+ passthrough: true
946
+ })),
947
+ _ts_metadata4("design:type", Function),
948
+ _ts_metadata4("design:paramtypes", [
949
+ Object,
950
+ Object
951
+ ]),
952
+ _ts_metadata4("design:returntype", Promise)
953
+ ], MediaConsoleAuthController.prototype, "session", null);
954
+ _ts_decorate4([
955
+ Post2("logout"),
956
+ HttpCode2(204),
957
+ _ts_param4(0, Req2()),
958
+ _ts_param4(1, Res({
959
+ passthrough: true
960
+ })),
961
+ _ts_metadata4("design:type", Function),
962
+ _ts_metadata4("design:paramtypes", [
963
+ Object,
964
+ Object
965
+ ]),
966
+ _ts_metadata4("design:returntype", void 0)
967
+ ], MediaConsoleAuthController.prototype, "logout", null);
968
+ MediaConsoleAuthController = _ts_decorate4([
969
+ Controller2(),
970
+ _ts_param4(0, Optional3()),
971
+ _ts_param4(0, Inject4(MEDIA_CONSOLE_AUTH)),
972
+ _ts_param4(1, Optional3()),
973
+ _ts_param4(1, Inject4(MEDIA_CONSOLE_COOKIE_PATH)),
974
+ _ts_metadata4("design:type", Function),
975
+ _ts_metadata4("design:paramtypes", [
976
+ Object,
977
+ Object
978
+ ])
979
+ ], MediaConsoleAuthController);
980
+
469
981
  // src/server/media-console-read.controller.ts
470
- import { Controller as Controller2, Get, Inject as Inject3, Param as Param2, Query as Query2, StreamableFile } from "@nestjs/common";
471
- function _ts_decorate3(decorators, target, key, desc) {
982
+ import { Controller as Controller3, Get as Get2, Inject as Inject5, Param as Param2, Query as Query2, StreamableFile, UseGuards as UseGuards2 } from "@nestjs/common";
983
+ function _ts_decorate5(decorators, target, key, desc) {
472
984
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
473
985
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
474
986
  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;
475
987
  return c > 3 && r && Object.defineProperty(target, key, r), r;
476
988
  }
477
- __name(_ts_decorate3, "_ts_decorate");
478
- function _ts_metadata3(k, v) {
989
+ __name(_ts_decorate5, "_ts_decorate");
990
+ function _ts_metadata5(k, v) {
479
991
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
480
992
  }
481
- __name(_ts_metadata3, "_ts_metadata");
482
- function _ts_param3(paramIndex, decorator) {
993
+ __name(_ts_metadata5, "_ts_metadata");
994
+ function _ts_param5(paramIndex, decorator) {
483
995
  return function(target, key) {
484
996
  decorator(target, key, paramIndex);
485
997
  };
486
998
  }
487
- __name(_ts_param3, "_ts_param");
999
+ __name(_ts_param5, "_ts_param");
488
1000
  function toLimit(value) {
489
1001
  if (value === void 0) return void 0;
490
1002
  const parsed = Number(value);
@@ -571,141 +1083,150 @@ var MediaConsoleReadController = class {
571
1083
  return this.service.topology();
572
1084
  }
573
1085
  };
574
- _ts_decorate3([
575
- Get("disks"),
576
- _ts_metadata3("design:type", Function),
577
- _ts_metadata3("design:paramtypes", []),
578
- _ts_metadata3("design:returntype", typeof DiskListResponse === "undefined" ? Object : DiskListResponse)
1086
+ _ts_decorate5([
1087
+ Get2("disks"),
1088
+ _ts_metadata5("design:type", Function),
1089
+ _ts_metadata5("design:paramtypes", []),
1090
+ _ts_metadata5("design:returntype", typeof DiskListResponse === "undefined" ? Object : DiskListResponse)
579
1091
  ], MediaConsoleReadController.prototype, "disks", null);
580
- _ts_decorate3([
581
- Get("disks/:disk/objects"),
582
- _ts_param3(0, Param2("disk")),
583
- _ts_param3(1, Query2("prefix")),
584
- _ts_param3(2, Query2("cursor")),
585
- _ts_param3(3, Query2("limit")),
586
- _ts_metadata3("design:type", Function),
587
- _ts_metadata3("design:paramtypes", [
1092
+ _ts_decorate5([
1093
+ Get2("disks/:disk/objects"),
1094
+ _ts_param5(0, Param2("disk")),
1095
+ _ts_param5(1, Query2("prefix")),
1096
+ _ts_param5(2, Query2("cursor")),
1097
+ _ts_param5(3, Query2("limit")),
1098
+ _ts_metadata5("design:type", Function),
1099
+ _ts_metadata5("design:paramtypes", [
588
1100
  String,
589
1101
  String,
590
1102
  String,
591
1103
  String
592
1104
  ]),
593
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1105
+ _ts_metadata5("design:returntype", typeof Promise === "undefined" ? Object : Promise)
594
1106
  ], MediaConsoleReadController.prototype, "objects", null);
595
- _ts_decorate3([
596
- Get("disks/:disk/object"),
597
- _ts_param3(0, Param2("disk")),
598
- _ts_param3(1, Query2("key")),
599
- _ts_metadata3("design:type", Function),
600
- _ts_metadata3("design:paramtypes", [
1107
+ _ts_decorate5([
1108
+ Get2("disks/:disk/object"),
1109
+ _ts_param5(0, Param2("disk")),
1110
+ _ts_param5(1, Query2("key")),
1111
+ _ts_metadata5("design:type", Function),
1112
+ _ts_metadata5("design:paramtypes", [
601
1113
  String,
602
1114
  String
603
1115
  ]),
604
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1116
+ _ts_metadata5("design:returntype", typeof Promise === "undefined" ? Object : Promise)
605
1117
  ], MediaConsoleReadController.prototype, "object", null);
606
- _ts_decorate3([
607
- Get("disks/:disk/object/raw"),
608
- _ts_param3(0, Param2("disk")),
609
- _ts_param3(1, Query2("key")),
610
- _ts_metadata3("design:type", Function),
611
- _ts_metadata3("design:paramtypes", [
1118
+ _ts_decorate5([
1119
+ Get2("disks/:disk/object/raw"),
1120
+ _ts_param5(0, Param2("disk")),
1121
+ _ts_param5(1, Query2("key")),
1122
+ _ts_metadata5("design:type", Function),
1123
+ _ts_metadata5("design:paramtypes", [
612
1124
  String,
613
1125
  String
614
1126
  ]),
615
- _ts_metadata3("design:returntype", Promise)
1127
+ _ts_metadata5("design:returntype", Promise)
616
1128
  ], MediaConsoleReadController.prototype, "objectRaw", null);
617
- _ts_decorate3([
618
- Get("uploads"),
619
- _ts_param3(0, Query2("disk")),
620
- _ts_param3(1, Query2("prefix")),
621
- _ts_metadata3("design:type", Function),
622
- _ts_metadata3("design:paramtypes", [
1129
+ _ts_decorate5([
1130
+ Get2("uploads"),
1131
+ _ts_param5(0, Query2("disk")),
1132
+ _ts_param5(1, Query2("prefix")),
1133
+ _ts_metadata5("design:type", Function),
1134
+ _ts_metadata5("design:paramtypes", [
623
1135
  String,
624
1136
  String
625
1137
  ]),
626
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1138
+ _ts_metadata5("design:returntype", typeof Promise === "undefined" ? Object : Promise)
627
1139
  ], MediaConsoleReadController.prototype, "uploads", null);
628
- _ts_decorate3([
629
- Get("uploads/:id"),
630
- _ts_param3(0, Param2("id")),
631
- _ts_metadata3("design:type", Function),
632
- _ts_metadata3("design:paramtypes", [
1140
+ _ts_decorate5([
1141
+ Get2("uploads/:id"),
1142
+ _ts_param5(0, Param2("id")),
1143
+ _ts_metadata5("design:type", Function),
1144
+ _ts_metadata5("design:paramtypes", [
633
1145
  String
634
1146
  ]),
635
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1147
+ _ts_metadata5("design:returntype", typeof Promise === "undefined" ? Object : Promise)
636
1148
  ], MediaConsoleReadController.prototype, "upload", null);
637
- _ts_decorate3([
638
- Get("library/collections"),
639
- _ts_metadata3("design:type", Function),
640
- _ts_metadata3("design:paramtypes", []),
641
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1149
+ _ts_decorate5([
1150
+ Get2("library/collections"),
1151
+ _ts_metadata5("design:type", Function),
1152
+ _ts_metadata5("design:paramtypes", []),
1153
+ _ts_metadata5("design:returntype", typeof Promise === "undefined" ? Object : Promise)
642
1154
  ], MediaConsoleReadController.prototype, "collections", null);
643
- _ts_decorate3([
644
- Get("library"),
645
- _ts_param3(0, Query2("collection")),
646
- _ts_param3(1, Query2("disk")),
647
- _ts_param3(2, Query2("cursor")),
648
- _ts_param3(3, Query2("limit")),
649
- _ts_metadata3("design:type", Function),
650
- _ts_metadata3("design:paramtypes", [
1155
+ _ts_decorate5([
1156
+ Get2("library"),
1157
+ _ts_param5(0, Query2("collection")),
1158
+ _ts_param5(1, Query2("disk")),
1159
+ _ts_param5(2, Query2("cursor")),
1160
+ _ts_param5(3, Query2("limit")),
1161
+ _ts_metadata5("design:type", Function),
1162
+ _ts_metadata5("design:paramtypes", [
651
1163
  String,
652
1164
  String,
653
1165
  String,
654
1166
  String
655
1167
  ]),
656
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1168
+ _ts_metadata5("design:returntype", typeof Promise === "undefined" ? Object : Promise)
657
1169
  ], MediaConsoleReadController.prototype, "library", null);
658
- _ts_decorate3([
659
- Get("library/:id"),
660
- _ts_param3(0, Param2("id")),
661
- _ts_metadata3("design:type", Function),
662
- _ts_metadata3("design:paramtypes", [
1170
+ _ts_decorate5([
1171
+ Get2("library/:id"),
1172
+ _ts_param5(0, Param2("id")),
1173
+ _ts_metadata5("design:type", Function),
1174
+ _ts_metadata5("design:paramtypes", [
663
1175
  String
664
1176
  ]),
665
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1177
+ _ts_metadata5("design:returntype", typeof Promise === "undefined" ? Object : Promise)
666
1178
  ], MediaConsoleReadController.prototype, "libraryRecord", null);
667
- _ts_decorate3([
668
- Get("topology"),
669
- _ts_metadata3("design:type", Function),
670
- _ts_metadata3("design:paramtypes", []),
671
- _ts_metadata3("design:returntype", typeof Topology === "undefined" ? Object : Topology)
1179
+ _ts_decorate5([
1180
+ Get2("topology"),
1181
+ _ts_metadata5("design:type", Function),
1182
+ _ts_metadata5("design:paramtypes", []),
1183
+ _ts_metadata5("design:returntype", typeof Topology === "undefined" ? Object : Topology)
672
1184
  ], MediaConsoleReadController.prototype, "topology", null);
673
- MediaConsoleReadController = _ts_decorate3([
674
- Controller2(),
675
- _ts_param3(0, Inject3(MediaConsoleService)),
676
- _ts_metadata3("design:type", Function),
677
- _ts_metadata3("design:paramtypes", [
1185
+ MediaConsoleReadController = _ts_decorate5([
1186
+ UseGuards2(MediaConsoleGuard),
1187
+ Controller3(),
1188
+ _ts_param5(0, Inject5(MediaConsoleService)),
1189
+ _ts_metadata5("design:type", Function),
1190
+ _ts_metadata5("design:paramtypes", [
678
1191
  typeof MediaConsoleService === "undefined" ? Object : MediaConsoleService
679
1192
  ])
680
1193
  ], MediaConsoleReadController);
681
1194
 
682
1195
  // src/server/media-console-api.module.ts
683
- function _ts_decorate4(decorators, target, key, desc) {
1196
+ function _ts_decorate6(decorators, target, key, desc) {
684
1197
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
685
1198
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
686
1199
  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;
687
1200
  return c > 3 && r && Object.defineProperty(target, key, r), r;
688
1201
  }
689
- __name(_ts_decorate4, "_ts_decorate");
1202
+ __name(_ts_decorate6, "_ts_decorate");
690
1203
  var MediaConsoleApiModule = class _MediaConsoleApiModule {
691
1204
  static {
692
1205
  __name(this, "MediaConsoleApiModule");
693
1206
  }
694
- static register(actions) {
1207
+ static register(options) {
695
1208
  return {
696
1209
  module: _MediaConsoleApiModule,
697
- controllers: actions ? [
1210
+ imports: options.imports ?? [],
1211
+ controllers: [
698
1212
  MediaConsoleReadController,
699
- MediaConsoleActionsController
700
- ] : [
701
- MediaConsoleReadController
1213
+ MediaConsoleAuthController,
1214
+ ...options.actions ? [
1215
+ MediaConsoleActionsController
1216
+ ] : []
702
1217
  ],
703
1218
  providers: [
704
1219
  MediaConsoleService,
1220
+ MediaConsoleGuard,
705
1221
  {
706
1222
  provide: MEDIA_DASHBOARD_ACTIONS,
707
- useValue: actions
708
- }
1223
+ useValue: options.actions
1224
+ },
1225
+ {
1226
+ provide: MEDIA_CONSOLE_COOKIE_PATH,
1227
+ useValue: options.cookiePath
1228
+ },
1229
+ options.authProvider
709
1230
  ],
710
1231
  exports: [
711
1232
  MediaConsoleService
@@ -713,7 +1234,7 @@ var MediaConsoleApiModule = class _MediaConsoleApiModule {
713
1234
  };
714
1235
  }
715
1236
  };
716
- MediaConsoleApiModule = _ts_decorate4([
1237
+ MediaConsoleApiModule = _ts_decorate6([
717
1238
  Module({})
718
1239
  ], MediaConsoleApiModule);
719
1240
 
@@ -721,24 +1242,24 @@ MediaConsoleApiModule = _ts_decorate4([
721
1242
  import { existsSync, readFileSync } from "node:fs";
722
1243
  import { basename, extname, join, resolve, sep } from "node:path";
723
1244
  import { fileURLToPath } from "node:url";
724
- import { Controller as Controller3, Get as Get2, Header, Inject as Inject4, NotFoundException as NotFoundException2, Param as Param3, StreamableFile as StreamableFile2 } from "@nestjs/common";
725
- function _ts_decorate5(decorators, target, key, desc) {
1245
+ import { Controller as Controller4, Get as Get3, Header, Inject as Inject6, NotFoundException as NotFoundException3, Param as Param3, StreamableFile as StreamableFile2 } from "@nestjs/common";
1246
+ function _ts_decorate7(decorators, target, key, desc) {
726
1247
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
727
1248
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
728
1249
  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;
729
1250
  return c > 3 && r && Object.defineProperty(target, key, r), r;
730
1251
  }
731
- __name(_ts_decorate5, "_ts_decorate");
732
- function _ts_metadata4(k, v) {
1252
+ __name(_ts_decorate7, "_ts_decorate");
1253
+ function _ts_metadata6(k, v) {
733
1254
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
734
1255
  }
735
- __name(_ts_metadata4, "_ts_metadata");
736
- function _ts_param4(paramIndex, decorator) {
1256
+ __name(_ts_metadata6, "_ts_metadata");
1257
+ function _ts_param6(paramIndex, decorator) {
737
1258
  return function(target, key) {
738
1259
  decorator(target, key, paramIndex);
739
1260
  };
740
1261
  }
741
- __name(_ts_param4, "_ts_param");
1262
+ __name(_ts_param6, "_ts_param");
742
1263
  var BUILD_BASE = "/media";
743
1264
  function spaDir() {
744
1265
  return fileURLToPath(new URL("../spa", import.meta.url));
@@ -769,7 +1290,7 @@ var MediaDashboardUiController = class {
769
1290
  index() {
770
1291
  const indexPath = join(this.dir, "index.html");
771
1292
  if (!existsSync(indexPath)) {
772
- throw new NotFoundException2("Console SPA is not built. Run the package build.");
1293
+ throw new NotFoundException3("Console SPA is not built. Run the package build.");
773
1294
  }
774
1295
  const html = readFileSync(indexPath, "utf8").replaceAll(`="${BUILD_BASE}/`, `="${this.basePath}/`);
775
1296
  const inject = `<script>window.__MEDIA_BASE__='${this.basePath}';window.__MEDIA_API__='${this.apiBasePath}';</script>`;
@@ -777,11 +1298,11 @@ var MediaDashboardUiController = class {
777
1298
  }
778
1299
  asset(file) {
779
1300
  const safe = basename(file);
780
- if (safe !== file) throw new NotFoundException2();
1301
+ if (safe !== file) throw new NotFoundException3();
781
1302
  const root = resolve(this.dir, "assets");
782
1303
  const assetPath = resolve(root, safe);
783
1304
  if (!assetPath.startsWith(root + sep) || !existsSync(assetPath)) {
784
- throw new NotFoundException2();
1305
+ throw new NotFoundException3();
785
1306
  }
786
1307
  const type = CONTENT_TYPES[extname(safe)] ?? "application/octet-stream";
787
1308
  return new StreamableFile2(readFileSync(assetPath), {
@@ -789,43 +1310,43 @@ var MediaDashboardUiController = class {
789
1310
  });
790
1311
  }
791
1312
  };
792
- _ts_decorate5([
793
- Get2(),
1313
+ _ts_decorate7([
1314
+ Get3(),
794
1315
  Header("Content-Type", "text/html; charset=utf-8"),
795
1316
  Header("Cache-Control", "no-store, must-revalidate"),
796
- _ts_metadata4("design:type", Function),
797
- _ts_metadata4("design:paramtypes", []),
798
- _ts_metadata4("design:returntype", String)
1317
+ _ts_metadata6("design:type", Function),
1318
+ _ts_metadata6("design:paramtypes", []),
1319
+ _ts_metadata6("design:returntype", String)
799
1320
  ], MediaDashboardUiController.prototype, "index", null);
800
- _ts_decorate5([
801
- Get2("assets/:file"),
1321
+ _ts_decorate7([
1322
+ Get3("assets/:file"),
802
1323
  Header("Cache-Control", "public, max-age=31536000, immutable"),
803
- _ts_param4(0, Param3("file")),
804
- _ts_metadata4("design:type", Function),
805
- _ts_metadata4("design:paramtypes", [
1324
+ _ts_param6(0, Param3("file")),
1325
+ _ts_metadata6("design:type", Function),
1326
+ _ts_metadata6("design:paramtypes", [
806
1327
  String
807
1328
  ]),
808
- _ts_metadata4("design:returntype", typeof StreamableFile2 === "undefined" ? Object : StreamableFile2)
1329
+ _ts_metadata6("design:returntype", typeof StreamableFile2 === "undefined" ? Object : StreamableFile2)
809
1330
  ], MediaDashboardUiController.prototype, "asset", null);
810
- MediaDashboardUiController = _ts_decorate5([
811
- Controller3(),
812
- _ts_param4(0, Inject4(MEDIA_DASHBOARD_BASE_PATH)),
813
- _ts_param4(1, Inject4(MEDIA_DASHBOARD_API_PATH)),
814
- _ts_metadata4("design:type", Function),
815
- _ts_metadata4("design:paramtypes", [
1331
+ MediaDashboardUiController = _ts_decorate7([
1332
+ Controller4(),
1333
+ _ts_param6(0, Inject6(MEDIA_DASHBOARD_BASE_PATH)),
1334
+ _ts_param6(1, Inject6(MEDIA_DASHBOARD_API_PATH)),
1335
+ _ts_metadata6("design:type", Function),
1336
+ _ts_metadata6("design:paramtypes", [
816
1337
  String,
817
1338
  String
818
1339
  ])
819
1340
  ], MediaDashboardUiController);
820
1341
 
821
1342
  // src/server/media-dashboard.module.ts
822
- function _ts_decorate6(decorators, target, key, desc) {
1343
+ function _ts_decorate8(decorators, target, key, desc) {
823
1344
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
824
1345
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
825
1346
  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;
826
1347
  return c > 3 && r && Object.defineProperty(target, key, r), r;
827
1348
  }
828
- __name(_ts_decorate6, "_ts_decorate");
1349
+ __name(_ts_decorate8, "_ts_decorate");
829
1350
  function normalize(path) {
830
1351
  return `/${path.replace(/^\/+|\/+$/g, "")}`;
831
1352
  }
@@ -835,13 +1356,34 @@ var MediaDashboardModule = class _MediaDashboardModule {
835
1356
  __name(this, "MediaDashboardModule");
836
1357
  }
837
1358
  static forRoot(options = {}) {
1359
+ const apiBasePath = normalize(options.apiBasePath ?? `${normalize(options.basePath ?? "/media")}/api`);
1360
+ return _MediaDashboardModule.build(options, apiBasePath, {
1361
+ provide: MEDIA_CONSOLE_AUTH,
1362
+ useValue: resolveConsoleAuth(options.auth)
1363
+ });
1364
+ }
1365
+ static forRootAsync(options) {
1366
+ const apiBasePath = normalize(options.apiBasePath ?? `${normalize(options.basePath ?? "/media")}/api`);
1367
+ const authProvider = {
1368
+ provide: MEDIA_CONSOLE_AUTH,
1369
+ inject: options.inject ?? [],
1370
+ useFactory: /* @__PURE__ */ __name(async (...deps) => resolveConsoleAuth(await options.useAuth(...deps)), "useFactory")
1371
+ };
1372
+ return _MediaDashboardModule.build(options, apiBasePath, authProvider, options.imports);
1373
+ }
1374
+ /** Shared wiring: static routing + the API module, with `auth` supplied by the given provider. */
1375
+ static build(options, apiBasePath, authProvider, imports) {
838
1376
  const basePath = normalize(options.basePath ?? "/media");
839
- const apiBasePath = normalize(options.apiBasePath ?? `${basePath}/api`);
840
1377
  const actions = options.actions === true;
841
1378
  return {
842
1379
  module: _MediaDashboardModule,
843
1380
  imports: [
844
- MediaConsoleApiModule.register(actions),
1381
+ MediaConsoleApiModule.register({
1382
+ actions,
1383
+ cookiePath: apiBasePath,
1384
+ authProvider,
1385
+ imports
1386
+ }),
845
1387
  RouterModule.register([
846
1388
  {
847
1389
  path: basePath,
@@ -873,7 +1415,7 @@ var MediaDashboardModule = class _MediaDashboardModule {
873
1415
  };
874
1416
  }
875
1417
  };
876
- MediaDashboardModule = _ts_decorate6([
1418
+ MediaDashboardModule = _ts_decorate8([
877
1419
  Module2({})
878
1420
  ], MediaDashboardModule);
879
1421
  export {