@tsdevstack/nest-common 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/dist/auth/auth-user.interface.d.ts +62 -0
  4. package/dist/auth/auth.guard.d.ts +181 -0
  5. package/dist/auth/auth.guard.test.d.ts +1 -0
  6. package/dist/auth/auth.module.d.ts +45 -0
  7. package/dist/auth/index.d.ts +17 -0
  8. package/dist/auth/partner-api.decorator.d.ts +42 -0
  9. package/dist/auth/partner.decorator.d.ts +60 -0
  10. package/dist/auth/partner.decorator.test.d.ts +1 -0
  11. package/dist/auth/public.decorator.d.ts +42 -0
  12. package/dist/auth/public.decorator.test.d.ts +1 -0
  13. package/dist/auth/utils/extract-user-from-headers.d.ts +45 -0
  14. package/dist/auth/utils/extract-user-from-headers.test.d.ts +1 -0
  15. package/dist/auth/utils/index.d.ts +8 -0
  16. package/dist/auth/utils/parse-header-value.d.ts +40 -0
  17. package/dist/auth/utils/parse-header-value.test.d.ts +1 -0
  18. package/dist/auth/utils/to-camel-case.d.ts +18 -0
  19. package/dist/auth/utils/to-camel-case.test.d.ts +1 -0
  20. package/dist/bootstrap/create-app.d.ts +31 -0
  21. package/dist/bootstrap/create-app.test.d.ts +1 -0
  22. package/dist/bootstrap/start-worker.d.ts +24 -0
  23. package/dist/bootstrap/start-worker.test.d.ts +1 -0
  24. package/dist/bull/bull-config.module.d.ts +22 -0
  25. package/dist/bull/bull-config.module.test.d.ts +1 -0
  26. package/dist/bull/index.d.ts +1 -0
  27. package/dist/config/load-framework-config.d.ts +32 -0
  28. package/dist/config/load-framework-config.test.d.ts +1 -0
  29. package/dist/database/prisma-connection.d.ts +48 -0
  30. package/dist/database/prisma-connection.test.d.ts +1 -0
  31. package/dist/email-rate-limit/email-rate-limit.decorator.d.ts +8 -0
  32. package/dist/email-rate-limit/email-rate-limit.decorator.test.d.ts +1 -0
  33. package/dist/email-rate-limit/email-rate-limit.guard.d.ts +11 -0
  34. package/dist/email-rate-limit/email-rate-limit.guard.test.d.ts +1 -0
  35. package/dist/email-rate-limit/email-rate-limit.module.d.ts +2 -0
  36. package/dist/health/health.controller.d.ts +11 -0
  37. package/dist/health/health.controller.test.d.ts +1 -0
  38. package/dist/health/health.interface.d.ts +31 -0
  39. package/dist/health/health.module.d.ts +5 -0
  40. package/dist/health/health.service.d.ts +12 -0
  41. package/dist/health/health.service.test.d.ts +1 -0
  42. package/dist/health/index.d.ts +6 -0
  43. package/dist/health/indicators/memory.indicator.d.ts +7 -0
  44. package/dist/health/indicators/memory.indicator.test.d.ts +1 -0
  45. package/dist/health/indicators/redis.indicator.d.ts +7 -0
  46. package/dist/health/indicators/redis.indicator.test.d.ts +1 -0
  47. package/dist/index.d.ts +40 -0
  48. package/dist/index.js +9 -0
  49. package/dist/index.mjs +9 -0
  50. package/dist/logging/index.d.ts +6 -0
  51. package/dist/logging/logger.interface.d.ts +29 -0
  52. package/dist/logging/logger.module.d.ts +14 -0
  53. package/dist/logging/logger.service.d.ts +31 -0
  54. package/dist/logging/logger.service.test.d.ts +1 -0
  55. package/dist/logging/logging.interceptor.d.ts +8 -0
  56. package/dist/logging/logging.interceptor.test.d.ts +1 -0
  57. package/dist/metrics/index.d.ts +5 -0
  58. package/dist/metrics/metrics.controller.d.ts +7 -0
  59. package/dist/metrics/metrics.controller.test.d.ts +1 -0
  60. package/dist/metrics/metrics.interceptor.d.ts +9 -0
  61. package/dist/metrics/metrics.interceptor.test.d.ts +1 -0
  62. package/dist/metrics/metrics.interface.d.ts +17 -0
  63. package/dist/metrics/metrics.module.d.ts +5 -0
  64. package/dist/metrics/metrics.service.d.ts +79 -0
  65. package/dist/metrics/metrics.service.test.d.ts +1 -0
  66. package/dist/notifications/index.d.ts +15 -0
  67. package/dist/notifications/interfaces/email-options.interface.d.ts +23 -0
  68. package/dist/notifications/interfaces/index.d.ts +6 -0
  69. package/dist/notifications/interfaces/push-options.interface.d.ts +16 -0
  70. package/dist/notifications/interfaces/sms-options.interface.d.ts +12 -0
  71. package/dist/notifications/notification.module.d.ts +2 -0
  72. package/dist/notifications/notification.module.test.d.ts +1 -0
  73. package/dist/notifications/notification.service.d.ts +28 -0
  74. package/dist/notifications/notification.service.test.d.ts +1 -0
  75. package/dist/notifications/providers/email/console.provider.d.ts +9 -0
  76. package/dist/notifications/providers/email/console.provider.test.d.ts +1 -0
  77. package/dist/notifications/providers/email/resend.provider.d.ts +24 -0
  78. package/dist/notifications/providers/email/resend.provider.test.d.ts +1 -0
  79. package/dist/notifications/providers/email-provider.interface.d.ts +17 -0
  80. package/dist/observability/index.d.ts +2 -0
  81. package/dist/observability/observability.interface.d.ts +32 -0
  82. package/dist/observability/observability.module.d.ts +24 -0
  83. package/dist/observability/observability.module.test.d.ts +1 -0
  84. package/dist/open-api-docs/create-swagger-document.d.ts +10 -0
  85. package/dist/open-api-docs/create-swagger-document.test.d.ts +1 -0
  86. package/dist/open-api-docs/generate-swagger-docs.d.ts +12 -0
  87. package/dist/open-api-docs/generate-swagger-docs.test.d.ts +1 -0
  88. package/dist/rate-limit/rate-limit-headers.interceptor.d.ts +5 -0
  89. package/dist/rate-limit/rate-limit-headers.interceptor.test.d.ts +1 -0
  90. package/dist/rate-limit/rate-limit.decorator.d.ts +11 -0
  91. package/dist/rate-limit/rate-limit.decorator.test.d.ts +1 -0
  92. package/dist/rate-limit/rate-limit.guard.d.ts +13 -0
  93. package/dist/rate-limit/rate-limit.guard.test.d.ts +1 -0
  94. package/dist/rate-limit/rate-limit.module.d.ts +2 -0
  95. package/dist/redis/redis.module.d.ts +2 -0
  96. package/dist/redis/redis.service.d.ts +17 -0
  97. package/dist/redis/redis.service.test.d.ts +1 -0
  98. package/dist/scheduler/index.d.ts +1 -0
  99. package/dist/scheduler/scheduler.guard.d.ts +73 -0
  100. package/dist/scheduler/scheduler.guard.test.d.ts +1 -0
  101. package/dist/secrets/index.d.ts +10 -0
  102. package/dist/secrets/providers/aws.provider.d.ts +56 -0
  103. package/dist/secrets/providers/aws.provider.test.d.ts +1 -0
  104. package/dist/secrets/providers/azure.provider.d.ts +70 -0
  105. package/dist/secrets/providers/azure.provider.test.d.ts +1 -0
  106. package/dist/secrets/providers/cloud-provider-adapter.d.ts +50 -0
  107. package/dist/secrets/providers/cloud-provider-adapter.test.d.ts +1 -0
  108. package/dist/secrets/providers/cloud-provider.interface.d.ts +86 -0
  109. package/dist/secrets/providers/gcp.provider.d.ts +64 -0
  110. package/dist/secrets/providers/gcp.provider.test.d.ts +1 -0
  111. package/dist/secrets/providers/local.provider.d.ts +82 -0
  112. package/dist/secrets/providers/local.provider.test.d.ts +1 -0
  113. package/dist/secrets/providers/provider-factory.d.ts +39 -0
  114. package/dist/secrets/providers/provider-factory.test.d.ts +1 -0
  115. package/dist/secrets/secrets.interface.d.ts +93 -0
  116. package/dist/secrets/secrets.module.d.ts +24 -0
  117. package/dist/secrets/secrets.service.d.ts +70 -0
  118. package/dist/secrets/secrets.service.test.d.ts +1 -0
  119. package/dist/service-client/base-service-client.d.ts +113 -0
  120. package/dist/service-client/base-service-client.test.d.ts +1 -0
  121. package/dist/service-client/filter-forward-headers.d.ts +11 -0
  122. package/dist/service-client/filter-forward-headers.test.d.ts +1 -0
  123. package/dist/telemetry/index.d.ts +4 -0
  124. package/dist/telemetry/telemetry.interface.d.ts +33 -0
  125. package/dist/telemetry/telemetry.module.d.ts +5 -0
  126. package/dist/telemetry/telemetry.service.d.ts +39 -0
  127. package/dist/telemetry/telemetry.service.test.d.ts +1 -0
  128. package/dist/telemetry/tracing.interceptor.d.ts +11 -0
  129. package/dist/telemetry/tracing.interceptor.test.d.ts +1 -0
  130. package/dist/utils/package-json.d.ts +25 -0
  131. package/package.json +102 -0
@@ -0,0 +1,79 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { type Counter, type Histogram, type UpDownCounter, type Meter } from '@opentelemetry/api';
3
+ import { TelemetryService } from '../telemetry/telemetry.service';
4
+ import type { MetricsModuleOptions } from './metrics.interface';
5
+ export declare class MetricsService implements OnModuleInit {
6
+ private readonly telemetryService?;
7
+ private meter;
8
+ private prefix;
9
+ private _httpRequestDuration;
10
+ private _httpRequestTotal;
11
+ private _httpActiveConnections;
12
+ constructor(options: MetricsModuleOptions, telemetryService?: TelemetryService | undefined);
13
+ onModuleInit(): void;
14
+ /**
15
+ * Record HTTP request duration
16
+ */
17
+ recordHttpRequestDuration(labels: {
18
+ method: string;
19
+ route: string;
20
+ status_code: string;
21
+ }, duration: number): void;
22
+ /**
23
+ * Increment HTTP request total
24
+ */
25
+ incrementHttpRequestTotal(labels: {
26
+ method: string;
27
+ route: string;
28
+ status_code: string;
29
+ }): void;
30
+ /**
31
+ * Increment active connections
32
+ */
33
+ incrementActiveConnections(): void;
34
+ /**
35
+ * Decrement active connections
36
+ */
37
+ decrementActiveConnections(): void;
38
+ /**
39
+ * Get the meter for creating custom metrics
40
+ */
41
+ getMeter(): Meter | undefined;
42
+ /**
43
+ * Create a custom counter
44
+ */
45
+ createCounter(name: string, options?: {
46
+ description?: string;
47
+ unit?: string;
48
+ }): Counter | undefined;
49
+ /**
50
+ * Create a custom histogram
51
+ */
52
+ createHistogram(name: string, options?: {
53
+ description?: string;
54
+ unit?: string;
55
+ }): Histogram | undefined;
56
+ /**
57
+ * Create a custom up/down counter (for gauge-like metrics)
58
+ */
59
+ createUpDownCounter(name: string, options?: {
60
+ description?: string;
61
+ unit?: string;
62
+ }): UpDownCounter | undefined;
63
+ /**
64
+ * Get metrics in Prometheus format (delegated to TelemetryService)
65
+ */
66
+ getMetrics(): Promise<string>;
67
+ /**
68
+ * Collect metrics in Prometheus format
69
+ */
70
+ private collectMetrics;
71
+ /**
72
+ * Get content type for Prometheus metrics
73
+ */
74
+ getContentType(): string;
75
+ /**
76
+ * Get the TelemetryService (for controller access to exporter)
77
+ */
78
+ getTelemetryService(): TelemetryService | undefined;
79
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Notifications Module
3
+ *
4
+ * Provides email (and future SMS/push) notification capabilities.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ export { NotificationModule } from './notification.module';
9
+ export { NotificationService, EMAIL_PROVIDER } from './notification.service';
10
+ export type { EmailOptions } from './interfaces/email-options.interface';
11
+ export type { SMSOptions } from './interfaces/sms-options.interface';
12
+ export type { PushOptions } from './interfaces/push-options.interface';
13
+ export type { EmailProvider } from './providers/email-provider.interface';
14
+ export { ConsoleEmailProvider } from './providers/email/console.provider';
15
+ export { ResendEmailProvider } from './providers/email/resend.provider';
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Email Options Interface
3
+ *
4
+ * Options for sending an email via NotificationService.sendEmail()
5
+ */
6
+ export interface EmailOptions {
7
+ /** Recipient email address(es) */
8
+ to: string | string[];
9
+ /** Email subject line */
10
+ subject: string;
11
+ /** HTML content of the email */
12
+ html?: string;
13
+ /** Plain text content (fallback if html not provided) */
14
+ text?: string;
15
+ /** Template name (for future template support) */
16
+ template?: string;
17
+ /** Data to pass to template (for future template support) */
18
+ data?: Record<string, unknown>;
19
+ /** From address (overrides default) */
20
+ from?: string;
21
+ /** Reply-to address */
22
+ replyTo?: string;
23
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Notification Interfaces
3
+ */
4
+ export type { EmailOptions } from './email-options.interface';
5
+ export type { SMSOptions } from './sms-options.interface';
6
+ export type { PushOptions } from './push-options.interface';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Push Notification Options Interface (Stub)
3
+ *
4
+ * Options for sending push notifications via NotificationService.sendPush()
5
+ * Note: Push notification support is not implemented in v1.
6
+ */
7
+ export interface PushOptions {
8
+ /** Device tokens to send notification to */
9
+ tokens: string[];
10
+ /** Notification title */
11
+ title: string;
12
+ /** Notification body */
13
+ body: string;
14
+ /** Additional data payload */
15
+ data?: Record<string, unknown>;
16
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * SMS Options Interface (Stub)
3
+ *
4
+ * Options for sending SMS via NotificationService.sendSMS()
5
+ * Note: SMS support is not implemented in v1.
6
+ */
7
+ export interface SMSOptions {
8
+ /** Recipient phone number */
9
+ to: string;
10
+ /** Message body */
11
+ body: string;
12
+ }
@@ -0,0 +1,2 @@
1
+ export declare class NotificationModule {
2
+ }
@@ -0,0 +1 @@
1
+ import './notification.module';
@@ -0,0 +1,28 @@
1
+ import type { EmailOptions } from './interfaces/email-options.interface';
2
+ import type { SMSOptions } from './interfaces/sms-options.interface';
3
+ import type { PushOptions } from './interfaces/push-options.interface';
4
+ import type { EmailProvider } from './providers/email-provider.interface';
5
+ export declare const EMAIL_PROVIDER = "EMAIL_PROVIDER";
6
+ export declare class NotificationService {
7
+ private readonly emailProvider;
8
+ constructor(emailProvider: EmailProvider);
9
+ /**
10
+ * Send an email
11
+ * Uses the configured email provider (Console for local, Resend for cloud)
12
+ */
13
+ sendEmail(options: EmailOptions): Promise<void>;
14
+ /**
15
+ * Send an SMS (not implemented)
16
+ * @throws Error - SMS not implemented in v1
17
+ */
18
+ sendSMS(_options: SMSOptions): Promise<void>;
19
+ /**
20
+ * Send a push notification (not implemented)
21
+ * @throws Error - Push not implemented in v1
22
+ */
23
+ sendPush(_options: PushOptions): Promise<void>;
24
+ /**
25
+ * Get the current email provider name
26
+ */
27
+ getEmailProviderName(): string;
28
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { EmailOptions } from '../../interfaces/email-options.interface';
2
+ import type { EmailProvider } from '../email-provider.interface';
3
+ import { LoggerService } from '../../../logging/logger.service';
4
+ export declare class ConsoleEmailProvider implements EmailProvider {
5
+ private readonly logger;
6
+ constructor(logger?: LoggerService);
7
+ send(options: EmailOptions): Promise<void>;
8
+ getName(): string;
9
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Resend Email Provider
3
+ *
4
+ * Sends emails via Resend API.
5
+ * Used for cloud environments (GCP, AWS, Azure).
6
+ *
7
+ * Requires secrets:
8
+ * - RESEND_API_KEY: Your Resend API key
9
+ * - EMAIL_FROM: Default sender address (optional, defaults to onboarding@resend.dev)
10
+ */
11
+ import { OnModuleInit } from '@nestjs/common';
12
+ import type { EmailOptions } from '../../interfaces/email-options.interface';
13
+ import type { EmailProvider } from '../email-provider.interface';
14
+ import { SecretsService } from '../../../secrets/secrets.service';
15
+ export declare class ResendEmailProvider implements EmailProvider, OnModuleInit {
16
+ private readonly secrets;
17
+ private readonly logger;
18
+ private client;
19
+ private defaultFrom;
20
+ constructor(secrets: SecretsService);
21
+ onModuleInit(): Promise<void>;
22
+ send(options: EmailOptions): Promise<void>;
23
+ getName(): string;
24
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Email Provider Interface
3
+ *
4
+ * All email providers (Console, Resend) must implement this interface.
5
+ */
6
+ import type { EmailOptions } from '../interfaces/email-options.interface';
7
+ export interface EmailProvider {
8
+ /**
9
+ * Send an email
10
+ * @param options - Email options (to, subject, html/text, etc.)
11
+ */
12
+ send(options: EmailOptions): Promise<void>;
13
+ /**
14
+ * Get the provider name (for logging/debugging)
15
+ */
16
+ getName(): string;
17
+ }
@@ -0,0 +1,2 @@
1
+ export { ObservabilityModule } from './observability.module';
2
+ export type { ObservabilityModuleOptions } from './observability.interface';
@@ -0,0 +1,32 @@
1
+ export interface ObservabilityModuleOptions {
2
+ /**
3
+ * Enable logging
4
+ * Default: true
5
+ */
6
+ logging?: boolean;
7
+ /**
8
+ * Enable metrics collection
9
+ * Default: true
10
+ */
11
+ metrics?: boolean;
12
+ /**
13
+ * Enable distributed tracing
14
+ * Default: true
15
+ */
16
+ tracing?: boolean;
17
+ /**
18
+ * Enable health endpoints
19
+ * Default: true
20
+ */
21
+ health?: boolean;
22
+ /**
23
+ * OTLP base endpoint for tracing (Jaeger, OTEL Collector, etc.)
24
+ * Default: OTEL_EXPORTER_OTLP_ENDPOINT env var or 'http://localhost:4318'
25
+ */
26
+ tracingEndpoint?: string;
27
+ /**
28
+ * Service name for telemetry identification
29
+ * Default: SERVICE_NAME env var
30
+ */
31
+ serviceName?: string;
32
+ }
@@ -0,0 +1,24 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import type { ObservabilityModuleOptions } from './observability.interface';
3
+ /**
4
+ * Unified observability module that provides logging, metrics, tracing, and health.
5
+ *
6
+ * Usage:
7
+ * ```typescript
8
+ * @Module({
9
+ * imports: [ObservabilityModule],
10
+ * })
11
+ * export class AppModule {}
12
+ * ```
13
+ *
14
+ * Or with options:
15
+ * ```typescript
16
+ * @Module({
17
+ * imports: [ObservabilityModule.forRoot({ tracing: false })],
18
+ * })
19
+ * export class AppModule {}
20
+ * ```
21
+ */
22
+ export declare class ObservabilityModule {
23
+ static forRoot(options?: ObservabilityModuleOptions): DynamicModule;
24
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import { INestApplication } from "@nestjs/common";
2
+ import { OpenAPIObject } from "@nestjs/swagger";
3
+ export interface SwaggerConfig {
4
+ title: string;
5
+ description: string;
6
+ version?: string;
7
+ tags?: string[];
8
+ globalPrefix?: string;
9
+ }
10
+ export declare function createSwaggerDocument(app: INestApplication, config: SwaggerConfig): OpenAPIObject;
@@ -0,0 +1,12 @@
1
+ import { Type } from '@nestjs/common';
2
+ import { OpenAPIObject } from '@nestjs/swagger';
3
+ /**
4
+ * Generate Swagger/OpenAPI documentation
5
+ *
6
+ * Reads service metadata from package.json automatically.
7
+ * No validation is performed - validation happens at dev/build time via CLI.
8
+ *
9
+ * @param AppModule - The NestJS application module
10
+ * @returns OpenAPI document object
11
+ */
12
+ export declare function generateSwaggerDocs<T>(AppModule: Type<T>): Promise<OpenAPIObject>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
2
+ import { Observable } from 'rxjs';
3
+ export declare class RateLimitHeadersInterceptor implements NestInterceptor {
4
+ intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { ExecutionContext } from '@nestjs/common';
2
+ export interface RateLimitOptions {
3
+ windowMs?: number;
4
+ maxRequests?: number;
5
+ keyGenerator?: 'ip' | 'apiKey' | 'userId' | 'custom';
6
+ customKeyGenerator?: (context: ExecutionContext) => string;
7
+ skipIf?: (context: ExecutionContext) => boolean;
8
+ message?: string;
9
+ }
10
+ export declare const RATE_LIMIT_KEY = "rateLimit";
11
+ export declare const RateLimitDecorator: (options: RateLimitOptions) => import("@nestjs/common").CustomDecorator<string>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import { CanActivate, ExecutionContext } from "@nestjs/common";
2
+ import { Reflector } from "@nestjs/core";
3
+ import { RedisService } from "../redis/redis.service";
4
+ export declare class RateLimitGuard implements CanActivate {
5
+ private readonly redisService;
6
+ private readonly reflector;
7
+ private readonly logger;
8
+ constructor(redisService: RedisService, reflector: Reflector);
9
+ canActivate(context: ExecutionContext): Promise<boolean>;
10
+ private checkRateLimit;
11
+ private generateKey;
12
+ private getClientIp;
13
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare class RateLimitModule {
2
+ }
@@ -0,0 +1,2 @@
1
+ export declare class RedisModule {
2
+ }
@@ -0,0 +1,17 @@
1
+ import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
2
+ import Redis from 'ioredis';
3
+ import { SecretsService } from '../secrets/secrets.service';
4
+ export declare class RedisService implements OnModuleInit, OnModuleDestroy {
5
+ private readonly secrets;
6
+ private redis;
7
+ private readonly logger;
8
+ constructor(secrets: SecretsService);
9
+ onModuleInit(): Promise<void>;
10
+ getClient(): Redis;
11
+ get(key: string): Promise<string | null>;
12
+ set(key: string, value: string, ttl?: number): Promise<boolean>;
13
+ incr(key: string): Promise<number | null>;
14
+ expire(key: string, seconds: number): Promise<boolean>;
15
+ del(key: string): Promise<boolean>;
16
+ onModuleDestroy(): void;
17
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export { SchedulerGuard } from './scheduler.guard';
@@ -0,0 +1,73 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import { SecretsService } from '../secrets/secrets.service';
3
+ /**
4
+ * SchedulerGuard
5
+ *
6
+ * Multi-cloud guard for scheduled job endpoints.
7
+ * Validates that requests come from the cloud scheduler, not external sources.
8
+ *
9
+ * Security model:
10
+ * - GCP: Full OIDC token validation (implemented)
11
+ * - AWS: EventBridge integration (not yet implemented - fails safe)
12
+ * - Azure: Logic Apps integration (not yet implemented - fails safe)
13
+ * - Development/Local: Skips validation for easy local testing
14
+ *
15
+ * Combined with @ApiExcludeController(), provides two-layer security:
16
+ * 1. @ApiExcludeController() keeps routes out of OpenAPI → no Kong route generated
17
+ * 2. SchedulerGuard validates OIDC token if someone hits endpoint directly
18
+ *
19
+ * Usage:
20
+ * ```typescript
21
+ * @ApiExcludeController() // Layer 1: Exclude from Kong
22
+ * @Controller('jobs')
23
+ * export class JobsController {
24
+ * @Post('cleanup-tokens')
25
+ * @UseGuards(SchedulerGuard) // Layer 2: Validate scheduler token
26
+ * async cleanupTokens() {
27
+ * // Only accessible from Cloud Scheduler
28
+ * }
29
+ * }
30
+ * ```
31
+ *
32
+ * Local testing:
33
+ * ```bash
34
+ * # SECRETS_PROVIDER=local skips validation
35
+ * curl -X POST http://localhost:3001/jobs/cleanup-tokens
36
+ * ```
37
+ */
38
+ export declare class SchedulerGuard implements CanActivate {
39
+ private readonly secrets;
40
+ private readonly logger;
41
+ private readonly oauth2Client;
42
+ constructor(secrets: SecretsService);
43
+ canActivate(context: ExecutionContext): Promise<boolean>;
44
+ /**
45
+ * Validates AWS EventBridge job invocation via shared secret.
46
+ *
47
+ * AWS EventBridge cannot make authenticated HTTP calls directly, so we use
48
+ * a Job Invoker Lambda that adds the X-Job-Secret header from Secrets Manager.
49
+ * This validates that header matches the expected secret.
50
+ *
51
+ * @param request - HTTP request with X-Job-Secret header
52
+ * @returns true if secret matches, false otherwise
53
+ */
54
+ private validateAwsJobSecret;
55
+ /**
56
+ * Validates Azure Container App Job invocation via shared secret.
57
+ *
58
+ * Azure Container App Jobs inject the JOB_SECRET env var from Terraform.
59
+ * The job's curl command sends it as X-Job-Secret header.
60
+ * This validates that header matches the expected secret from Key Vault.
61
+ */
62
+ private validateAzureJobSecret;
63
+ /**
64
+ * Validates GCP Cloud Scheduler OIDC token.
65
+ *
66
+ * Cloud Scheduler sends requests with an OIDC token in the Authorization header.
67
+ * We verify the token was issued by Google for our service URL.
68
+ *
69
+ * @param request - HTTP request with Authorization header
70
+ * @returns true if token is valid, false otherwise
71
+ */
72
+ private validateGcpOidc;
73
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Secrets Management Module
3
+ *
4
+ * Provides unified secrets management across local development and cloud environments.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ export * from './secrets.interface';
9
+ export * from './secrets.service';
10
+ export * from './providers/local.provider';
@@ -0,0 +1,56 @@
1
+ import { CloudSecretsProvider, CloudProviderConfig } from './cloud-provider.interface';
2
+ export declare class AWSSecretsProvider implements CloudSecretsProvider {
3
+ private client;
4
+ private projectName;
5
+ private serviceName;
6
+ private region;
7
+ private cache;
8
+ private readonly CACHE_TTL_MS;
9
+ constructor(config: CloudProviderConfig);
10
+ /**
11
+ * Get secret with service-scoped → shared fallback and caching
12
+ */
13
+ get(key: string): Promise<string | null>;
14
+ /**
15
+ * Set a secret with optional metadata tags
16
+ */
17
+ set(key: string, value: string, metadata?: Record<string, string>): Promise<void>;
18
+ /**
19
+ * Remove a secret
20
+ */
21
+ remove(key: string): Promise<void>;
22
+ /**
23
+ * List all secrets for this service (both service-scoped and shared)
24
+ */
25
+ list(): Promise<string[]>;
26
+ /**
27
+ * Check if a secret exists (checks both service-scoped and shared)
28
+ */
29
+ exists(key: string): Promise<boolean>;
30
+ getProviderName(): string;
31
+ /**
32
+ * Build secret name following convention: {projectName}-{scope}-{KEY}
33
+ */
34
+ private buildSecretName;
35
+ /**
36
+ * Extract key from secret name
37
+ * Input: "tsdevstack-auth-service-DATABASE_URL" or "tsdevstack-shared-DATABASE_URL"
38
+ * Output: "DATABASE_URL"
39
+ */
40
+ private extractKeyFromSecretName;
41
+ /**
42
+ * Fetch secret value from AWS
43
+ */
44
+ private fetchSecretFromAWS;
45
+ /**
46
+ * Build AWS tags from metadata
47
+ * AWS supports up to 50 tags per secret
48
+ */
49
+ private buildTags;
50
+ /**
51
+ * Cache management methods
52
+ */
53
+ private getFromCache;
54
+ private setCache;
55
+ private invalidateCache;
56
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,70 @@
1
+ import { CloudSecretsProvider, CloudProviderConfig } from './cloud-provider.interface';
2
+ export declare class AzureSecretsProvider implements CloudSecretsProvider {
3
+ private client;
4
+ private projectName;
5
+ private serviceName;
6
+ private keyVaultName;
7
+ private cache;
8
+ private readonly CACHE_TTL_MS;
9
+ constructor(config: CloudProviderConfig);
10
+ /**
11
+ * Get secret with service-scoped → shared fallback and caching
12
+ */
13
+ get(key: string): Promise<string | null>;
14
+ /**
15
+ * Set a secret with optional metadata tags
16
+ */
17
+ set(key: string, value: string, metadata?: Record<string, string>): Promise<void>;
18
+ /**
19
+ * Remove a secret
20
+ * Note: Azure soft-deletes secrets by default (recoverable for 90 days)
21
+ */
22
+ remove(key: string): Promise<void>;
23
+ /**
24
+ * List all secrets for this service (both service-scoped and shared)
25
+ */
26
+ list(): Promise<string[]>;
27
+ /**
28
+ * Check if a secret exists (checks both service-scoped and shared)
29
+ */
30
+ exists(key: string): Promise<boolean>;
31
+ getProviderName(): string;
32
+ /**
33
+ * Build secret name following convention: {projectName}-{scope}-{KEY}
34
+ * Azure Key Vault only allows alphanumeric and hyphens
35
+ * Transform underscores to hyphens: DATABASE_URL → DATABASE-URL
36
+ */
37
+ private buildSecretName;
38
+ /**
39
+ * Extract key from secret name and reverse transform
40
+ * Input: "tsdevstack-auth-service-DATABASE-URL" or "tsdevstack-shared-DATABASE-URL"
41
+ * Output: "DATABASE_URL"
42
+ */
43
+ private extractKeyFromSecretName;
44
+ /**
45
+ * Fetch secret value from Azure
46
+ */
47
+ private fetchSecretFromAzure;
48
+ /**
49
+ * Build Azure tags from metadata
50
+ * Azure supports up to 15 tags per secret
51
+ */
52
+ private buildTags;
53
+ /**
54
+ * Transform key to Azure-compatible format
55
+ * Azure Key Vault only allows alphanumeric and hyphens
56
+ * DATABASE_URL → DATABASE-URL
57
+ */
58
+ private transformKey;
59
+ /**
60
+ * Reverse transform Azure key back to standard format
61
+ * DATABASE-URL → DATABASE_URL
62
+ */
63
+ private reverseTransformKey;
64
+ /**
65
+ * Cache management methods
66
+ */
67
+ private getFromCache;
68
+ private setCache;
69
+ private invalidateCache;
70
+ }
@@ -0,0 +1 @@
1
+ export {};