@digilogiclabs/platform-core 1.16.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/auth.d.mts CHANGED
@@ -518,6 +518,20 @@ interface SecureTimedAudit {
518
518
  success: (metadata?: Record<string, unknown>) => Promise<void>;
519
519
  failure: (reason: string, metadata?: Record<string, unknown>) => Promise<void>;
520
520
  }
521
+ /** Authentication method — how the request was authenticated */
522
+ type SecureAuthMethod = "session" | "legacy_token" | "none";
523
+ /**
524
+ * Object-style audit configuration (used by DLL and other apps with
525
+ * structured audit enums). This is an alternative to the flat string form.
526
+ */
527
+ interface SecureAuditConfig {
528
+ /** The audit action (string or enum value) */
529
+ action: string;
530
+ /** Resource type being acted upon */
531
+ resource?: string;
532
+ /** Extract resource ID from request/params for audit (called after validation) */
533
+ getResourceId?: (request: Request, params: Record<string, string>, validated: unknown) => string | undefined;
534
+ }
521
535
  /** Per-route config */
522
536
  interface SecureRouteConfig<TValidated = unknown, TPresetKey extends string = string> {
523
537
  /** Rate limit preset key */
@@ -540,11 +554,16 @@ interface SecureRouteConfig<TValidated = unknown, TPresetKey extends string = st
540
554
  };
541
555
  };
542
556
  };
543
- /** Audit action name */
544
- audit?: string;
545
- /** Audit resource type */
557
+ /**
558
+ * Audit configuration — accepts either:
559
+ * - A string (action name, with optional `auditResource` for resource type)
560
+ * - An object `{ action, resource?, getResourceId? }` for structured audit enums
561
+ */
562
+ audit?: string | SecureAuditConfig;
563
+ /** Audit resource type (used when `audit` is a string) */
546
564
  auditResource?: string;
547
- /** Extract resource ID from request/params for audit (called after validation) */
565
+ /** Extract resource ID from request/params for audit (called after validation).
566
+ * Used when `audit` is a string. When `audit` is an object, use its `getResourceId` instead. */
548
567
  getResourceId?: (request: Request, params: Record<string, string>, validated: unknown) => string | undefined;
549
568
  /** Custom operation name for logging */
550
569
  operation?: string;
@@ -555,6 +574,8 @@ interface SecureRouteContext<TSession extends SecureSession = SecureSession, TVa
555
574
  session: TSession | null;
556
575
  /** Whether request was authenticated via legacy token */
557
576
  isLegacyToken: boolean;
577
+ /** How the request was authenticated */
578
+ authMethod: SecureAuthMethod;
558
579
  /** Whether the user has admin privileges */
559
580
  isAdmin: boolean;
560
581
  /** Validated input data */
@@ -599,4 +620,4 @@ declare function createSecureHandlerFactory<TSession extends SecureSession = Sec
599
620
  }) => Promise<Response>;
600
621
  };
601
622
 
602
- export { type FederatedLogoutConfig, type LazyRateLimitStoreOptions, RateLimitOptions, type RateLimitResult, RateLimitRule, RateLimitStore, type RedisRateLimitClient, type RedisRateLimitStoreOptions, type SecureHandlerFactoryConfig, type SecureLogger, type SecureRateLimitResult, type SecureRouteConfig, type SecureRouteContext, type SecureRouteHandler, type SecureSession, type SecureTimedAudit, addRateLimitHeaders, buildFederatedLogoutHandler, createLazyRateLimitStore, createRedisRateLimitStore, createSecureHandlerFactory, enforceRateLimit, errorResponse, extractBearerToken, getClientIp, isValidBearerToken, rateLimitResponse, safeValidate, verifyCronAuth, zodErrorResponse };
623
+ export { type FederatedLogoutConfig, type LazyRateLimitStoreOptions, RateLimitOptions, type RateLimitResult, RateLimitRule, RateLimitStore, type RedisRateLimitClient, type RedisRateLimitStoreOptions, type SecureAuditConfig, type SecureAuthMethod, type SecureHandlerFactoryConfig, type SecureLogger, type SecureRateLimitResult, type SecureRouteConfig, type SecureRouteContext, type SecureRouteHandler, type SecureSession, type SecureTimedAudit, addRateLimitHeaders, buildFederatedLogoutHandler, createLazyRateLimitStore, createRedisRateLimitStore, createSecureHandlerFactory, enforceRateLimit, errorResponse, extractBearerToken, getClientIp, isValidBearerToken, rateLimitResponse, safeValidate, verifyCronAuth, zodErrorResponse };
package/dist/auth.d.ts CHANGED
@@ -518,6 +518,20 @@ interface SecureTimedAudit {
518
518
  success: (metadata?: Record<string, unknown>) => Promise<void>;
519
519
  failure: (reason: string, metadata?: Record<string, unknown>) => Promise<void>;
520
520
  }
521
+ /** Authentication method — how the request was authenticated */
522
+ type SecureAuthMethod = "session" | "legacy_token" | "none";
523
+ /**
524
+ * Object-style audit configuration (used by DLL and other apps with
525
+ * structured audit enums). This is an alternative to the flat string form.
526
+ */
527
+ interface SecureAuditConfig {
528
+ /** The audit action (string or enum value) */
529
+ action: string;
530
+ /** Resource type being acted upon */
531
+ resource?: string;
532
+ /** Extract resource ID from request/params for audit (called after validation) */
533
+ getResourceId?: (request: Request, params: Record<string, string>, validated: unknown) => string | undefined;
534
+ }
521
535
  /** Per-route config */
522
536
  interface SecureRouteConfig<TValidated = unknown, TPresetKey extends string = string> {
523
537
  /** Rate limit preset key */
@@ -540,11 +554,16 @@ interface SecureRouteConfig<TValidated = unknown, TPresetKey extends string = st
540
554
  };
541
555
  };
542
556
  };
543
- /** Audit action name */
544
- audit?: string;
545
- /** Audit resource type */
557
+ /**
558
+ * Audit configuration — accepts either:
559
+ * - A string (action name, with optional `auditResource` for resource type)
560
+ * - An object `{ action, resource?, getResourceId? }` for structured audit enums
561
+ */
562
+ audit?: string | SecureAuditConfig;
563
+ /** Audit resource type (used when `audit` is a string) */
546
564
  auditResource?: string;
547
- /** Extract resource ID from request/params for audit (called after validation) */
565
+ /** Extract resource ID from request/params for audit (called after validation).
566
+ * Used when `audit` is a string. When `audit` is an object, use its `getResourceId` instead. */
548
567
  getResourceId?: (request: Request, params: Record<string, string>, validated: unknown) => string | undefined;
549
568
  /** Custom operation name for logging */
550
569
  operation?: string;
@@ -555,6 +574,8 @@ interface SecureRouteContext<TSession extends SecureSession = SecureSession, TVa
555
574
  session: TSession | null;
556
575
  /** Whether request was authenticated via legacy token */
557
576
  isLegacyToken: boolean;
577
+ /** How the request was authenticated */
578
+ authMethod: SecureAuthMethod;
558
579
  /** Whether the user has admin privileges */
559
580
  isAdmin: boolean;
560
581
  /** Validated input data */
@@ -599,4 +620,4 @@ declare function createSecureHandlerFactory<TSession extends SecureSession = Sec
599
620
  }) => Promise<Response>;
600
621
  };
601
622
 
602
- export { type FederatedLogoutConfig, type LazyRateLimitStoreOptions, RateLimitOptions, type RateLimitResult, RateLimitRule, RateLimitStore, type RedisRateLimitClient, type RedisRateLimitStoreOptions, type SecureHandlerFactoryConfig, type SecureLogger, type SecureRateLimitResult, type SecureRouteConfig, type SecureRouteContext, type SecureRouteHandler, type SecureSession, type SecureTimedAudit, addRateLimitHeaders, buildFederatedLogoutHandler, createLazyRateLimitStore, createRedisRateLimitStore, createSecureHandlerFactory, enforceRateLimit, errorResponse, extractBearerToken, getClientIp, isValidBearerToken, rateLimitResponse, safeValidate, verifyCronAuth, zodErrorResponse };
623
+ export { type FederatedLogoutConfig, type LazyRateLimitStoreOptions, RateLimitOptions, type RateLimitResult, RateLimitRule, RateLimitStore, type RedisRateLimitClient, type RedisRateLimitStoreOptions, type SecureAuditConfig, type SecureAuthMethod, type SecureHandlerFactoryConfig, type SecureLogger, type SecureRateLimitResult, type SecureRouteConfig, type SecureRouteContext, type SecureRouteHandler, type SecureSession, type SecureTimedAudit, addRateLimitHeaders, buildFederatedLogoutHandler, createLazyRateLimitStore, createRedisRateLimitStore, createSecureHandlerFactory, enforceRateLimit, errorResponse, extractBearerToken, getClientIp, isValidBearerToken, rateLimitResponse, safeValidate, verifyCronAuth, zodErrorResponse };
package/dist/auth.js CHANGED
@@ -1595,6 +1595,10 @@ function createSecureHandlerFactory(factoryConfig) {
1595
1595
  let isAdmin = false;
1596
1596
  let isLegacyToken = false;
1597
1597
  let timedAudit;
1598
+ const auditCfg = routeConfig.audit;
1599
+ const resolvedAuditAction = typeof auditCfg === "object" && auditCfg !== null ? auditCfg.action : auditCfg;
1600
+ const resolvedAuditResource = typeof auditCfg === "object" && auditCfg !== null ? auditCfg.resource : routeConfig.auditResource;
1601
+ const resolvedGetResourceId = typeof auditCfg === "object" && auditCfg !== null ? auditCfg.getResourceId : routeConfig.getResourceId;
1598
1602
  try {
1599
1603
  if (routeConfig.requireAuth || routeConfig.requireAdmin || routeConfig.requireRoles?.length) {
1600
1604
  session = await factoryConfig.getSession();
@@ -1665,17 +1669,17 @@ function createSecureHandlerFactory(factoryConfig) {
1665
1669
  const actorId = isLegacyToken ? "admin_token" : session?.user?.id || "anonymous";
1666
1670
  const actorType = isLegacyToken ? "admin" : "user";
1667
1671
  const actorEmail = session?.user?.email ?? void 0;
1668
- const resourceId = routeConfig.getResourceId ? routeConfig.getResourceId(
1672
+ const resourceId = resolvedGetResourceId ? resolvedGetResourceId(
1669
1673
  request,
1670
1674
  params,
1671
1675
  validated
1672
1676
  ) : void 0;
1673
- if (routeConfig.audit && factoryConfig.createTimedAudit) {
1677
+ if (resolvedAuditAction && factoryConfig.createTimedAudit) {
1674
1678
  timedAudit = factoryConfig.createTimedAudit(
1675
1679
  {
1676
- action: routeConfig.audit,
1677
- resource: routeConfig.auditResource ? {
1678
- type: routeConfig.auditResource,
1680
+ action: resolvedAuditAction,
1681
+ resource: resolvedAuditResource ? {
1682
+ type: resolvedAuditResource,
1679
1683
  id: resourceId
1680
1684
  } : void 0,
1681
1685
  actor: {
@@ -1687,9 +1691,11 @@ function createSecureHandlerFactory(factoryConfig) {
1687
1691
  request
1688
1692
  );
1689
1693
  }
1694
+ const authMethod = isLegacyToken ? "legacy_token" : session?.user ? "session" : "none";
1690
1695
  const ctx = {
1691
1696
  session,
1692
1697
  isLegacyToken,
1698
+ authMethod,
1693
1699
  isAdmin,
1694
1700
  validated,
1695
1701
  logger: log,
@@ -1699,16 +1705,16 @@ function createSecureHandlerFactory(factoryConfig) {
1699
1705
  };
1700
1706
  const response = await handler(request, ctx);
1701
1707
  response.headers.set("X-Request-ID", requestId);
1702
- if (routeConfig.audit && factoryConfig.auditLog && !timedAudit) {
1708
+ if (resolvedAuditAction && factoryConfig.auditLog && !timedAudit) {
1703
1709
  await factoryConfig.auditLog({
1704
1710
  actor: {
1705
1711
  id: actorId,
1706
1712
  type: actorType,
1707
1713
  email: actorEmail
1708
1714
  },
1709
- action: routeConfig.audit,
1710
- resource: routeConfig.auditResource ? {
1711
- type: routeConfig.auditResource,
1715
+ action: resolvedAuditAction,
1716
+ resource: resolvedAuditResource ? {
1717
+ type: resolvedAuditResource,
1712
1718
  id: resourceId ?? "unknown"
1713
1719
  } : void 0,
1714
1720
  outcome: "success"
@@ -1724,13 +1730,13 @@ function createSecureHandlerFactory(factoryConfig) {
1724
1730
  if (timedAudit) {
1725
1731
  await timedAudit.failure(errReason).catch(() => {
1726
1732
  });
1727
- } else if (routeConfig.audit && factoryConfig.auditLog) {
1733
+ } else if (resolvedAuditAction && factoryConfig.auditLog) {
1728
1734
  await factoryConfig.auditLog({
1729
1735
  actor: {
1730
1736
  id: session?.user?.id || "unknown",
1731
1737
  type: "user"
1732
1738
  },
1733
- action: routeConfig.audit,
1739
+ action: resolvedAuditAction,
1734
1740
  outcome: "failure",
1735
1741
  reason: errReason
1736
1742
  }).catch(() => {