@channel.io/app-sdk-server 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/dist/__tests__/decorators.test.d.ts +2 -0
  2. package/dist/__tests__/decorators.test.d.ts.map +1 -0
  3. package/dist/__tests__/decorators.test.js +259 -0
  4. package/dist/__tests__/decorators.test.js.map +1 -0
  5. package/dist/__tests__/testing-utils.test.d.ts +2 -0
  6. package/dist/__tests__/testing-utils.test.d.ts.map +1 -0
  7. package/dist/__tests__/testing-utils.test.js +118 -0
  8. package/dist/__tests__/testing-utils.test.js.map +1 -0
  9. package/dist/appstore/client.d.ts +70 -0
  10. package/dist/appstore/client.d.ts.map +1 -0
  11. package/dist/appstore/client.js +141 -0
  12. package/dist/appstore/client.js.map +1 -0
  13. package/dist/appstore/index.d.ts +3 -0
  14. package/dist/appstore/index.d.ts.map +1 -0
  15. package/dist/appstore/index.js +3 -0
  16. package/dist/appstore/index.js.map +1 -0
  17. package/dist/appstore/types.d.ts +87 -0
  18. package/dist/appstore/types.d.ts.map +1 -0
  19. package/dist/appstore/types.js +5 -0
  20. package/dist/appstore/types.js.map +1 -0
  21. package/dist/decorators/extension.decorator.d.ts +33 -0
  22. package/dist/decorators/extension.decorator.d.ts.map +1 -0
  23. package/dist/decorators/extension.decorator.js +36 -0
  24. package/dist/decorators/extension.decorator.js.map +1 -0
  25. package/dist/decorators/function.decorator.d.ts +34 -0
  26. package/dist/decorators/function.decorator.d.ts.map +1 -0
  27. package/dist/decorators/function.decorator.js +45 -0
  28. package/dist/decorators/function.decorator.js.map +1 -0
  29. package/dist/decorators/index.d.ts +5 -0
  30. package/dist/decorators/index.d.ts.map +1 -0
  31. package/dist/decorators/index.js +9 -0
  32. package/dist/decorators/index.js.map +1 -0
  33. package/dist/decorators/param.decorator.d.ts +49 -0
  34. package/dist/decorators/param.decorator.d.ts.map +1 -0
  35. package/dist/decorators/param.decorator.js +62 -0
  36. package/dist/decorators/param.decorator.js.map +1 -0
  37. package/dist/decorators/schema.decorator.d.ts +48 -0
  38. package/dist/decorators/schema.decorator.d.ts.map +1 -0
  39. package/dist/decorators/schema.decorator.js +59 -0
  40. package/dist/decorators/schema.decorator.js.map +1 -0
  41. package/dist/discovery/extension-discovery.service.d.ts +45 -0
  42. package/dist/discovery/extension-discovery.service.d.ts.map +1 -0
  43. package/dist/discovery/extension-discovery.service.js +192 -0
  44. package/dist/discovery/extension-discovery.service.js.map +1 -0
  45. package/dist/discovery/index.d.ts +3 -0
  46. package/dist/discovery/index.d.ts.map +1 -0
  47. package/dist/discovery/index.js +2 -0
  48. package/dist/discovery/index.js.map +1 -0
  49. package/dist/discovery/metadata.interface.d.ts +42 -0
  50. package/dist/discovery/metadata.interface.d.ts.map +1 -0
  51. package/dist/discovery/metadata.interface.js +2 -0
  52. package/dist/discovery/metadata.interface.js.map +1 -0
  53. package/dist/guards/index.d.ts +3 -0
  54. package/dist/guards/index.d.ts.map +1 -0
  55. package/dist/guards/index.js +3 -0
  56. package/dist/guards/index.js.map +1 -0
  57. package/dist/guards/signature.guard.d.ts +65 -0
  58. package/dist/guards/signature.guard.d.ts.map +1 -0
  59. package/dist/guards/signature.guard.js +156 -0
  60. package/dist/guards/signature.guard.js.map +1 -0
  61. package/dist/guards/signature.middleware.d.ts +76 -0
  62. package/dist/guards/signature.middleware.d.ts.map +1 -0
  63. package/dist/guards/signature.middleware.js +110 -0
  64. package/dist/guards/signature.middleware.js.map +1 -0
  65. package/dist/index.d.ts +11 -0
  66. package/dist/index.d.ts.map +1 -0
  67. package/dist/index.js +21 -0
  68. package/dist/index.js.map +1 -0
  69. package/dist/native/client.d.ts +105 -0
  70. package/dist/native/client.d.ts.map +1 -0
  71. package/dist/native/client.js +210 -0
  72. package/dist/native/client.js.map +1 -0
  73. package/dist/native/index.d.ts +3 -0
  74. package/dist/native/index.d.ts.map +1 -0
  75. package/dist/native/index.js +3 -0
  76. package/dist/native/index.js.map +1 -0
  77. package/dist/native/types.d.ts +198 -0
  78. package/dist/native/types.d.ts.map +1 -0
  79. package/dist/native/types.js +8 -0
  80. package/dist/native/types.js.map +1 -0
  81. package/dist/nestjs/channel-app.controller.d.ts +22 -0
  82. package/dist/nestjs/channel-app.controller.d.ts.map +1 -0
  83. package/dist/nestjs/channel-app.controller.js +87 -0
  84. package/dist/nestjs/channel-app.controller.js.map +1 -0
  85. package/dist/nestjs/channel-app.module.d.ts +47 -0
  86. package/dist/nestjs/channel-app.module.d.ts.map +1 -0
  87. package/dist/nestjs/channel-app.module.js +93 -0
  88. package/dist/nestjs/channel-app.module.js.map +1 -0
  89. package/dist/nestjs/channel-app.service.d.ts +44 -0
  90. package/dist/nestjs/channel-app.service.d.ts.map +1 -0
  91. package/dist/nestjs/channel-app.service.js +190 -0
  92. package/dist/nestjs/channel-app.service.js.map +1 -0
  93. package/dist/nestjs/index.d.ts +5 -0
  94. package/dist/nestjs/index.d.ts.map +1 -0
  95. package/dist/nestjs/index.js +5 -0
  96. package/dist/nestjs/index.js.map +1 -0
  97. package/dist/nestjs/types.d.ts +70 -0
  98. package/dist/nestjs/types.d.ts.map +1 -0
  99. package/dist/nestjs/types.js +5 -0
  100. package/dist/nestjs/types.js.map +1 -0
  101. package/dist/simple/channel-app.d.ts +80 -0
  102. package/dist/simple/channel-app.d.ts.map +1 -0
  103. package/dist/simple/channel-app.js +253 -0
  104. package/dist/simple/channel-app.js.map +1 -0
  105. package/dist/simple/index.d.ts +2 -0
  106. package/dist/simple/index.d.ts.map +1 -0
  107. package/dist/simple/index.js +2 -0
  108. package/dist/simple/index.js.map +1 -0
  109. package/dist/testing/index.d.ts +9 -0
  110. package/dist/testing/index.d.ts.map +1 -0
  111. package/dist/testing/index.js +9 -0
  112. package/dist/testing/index.js.map +1 -0
  113. package/dist/testing/mock-context.d.ts +32 -0
  114. package/dist/testing/mock-context.d.ts.map +1 -0
  115. package/dist/testing/mock-context.js +33 -0
  116. package/dist/testing/mock-context.js.map +1 -0
  117. package/dist/testing/test-extension.d.ts +60 -0
  118. package/dist/testing/test-extension.d.ts.map +1 -0
  119. package/dist/testing/test-extension.js +113 -0
  120. package/dist/testing/test-extension.js.map +1 -0
  121. package/dist/token/cache.d.ts +31 -0
  122. package/dist/token/cache.d.ts.map +1 -0
  123. package/dist/token/cache.js +69 -0
  124. package/dist/token/cache.js.map +1 -0
  125. package/dist/token/index.d.ts +4 -0
  126. package/dist/token/index.d.ts.map +1 -0
  127. package/dist/token/index.js +4 -0
  128. package/dist/token/index.js.map +1 -0
  129. package/dist/token/manager.d.ts +111 -0
  130. package/dist/token/manager.d.ts.map +1 -0
  131. package/dist/token/manager.js +246 -0
  132. package/dist/token/manager.js.map +1 -0
  133. package/dist/token/types.d.ts +85 -0
  134. package/dist/token/types.d.ts.map +1 -0
  135. package/dist/token/types.js +5 -0
  136. package/dist/token/types.js.map +1 -0
  137. package/package.json +69 -0
@@ -0,0 +1,192 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var ExtensionDiscoveryService_1;
11
+ import { Injectable, Logger } from "@nestjs/common";
12
+ import { DiscoveryService, Reflector } from "@nestjs/core";
13
+ import { zodToJsonSchema } from "zod-to-json-schema";
14
+ import { EXTENSION_METADATA, FUNCTION_METADATA, FUNCTIONS_METADATA, INPUT_SCHEMA_METADATA, OUTPUT_SCHEMA_METADATA, DESCRIPTION_METADATA, PARAM_METADATA, FunctionParamType, } from "../decorators/index.js";
15
+ let ExtensionDiscoveryService = ExtensionDiscoveryService_1 = class ExtensionDiscoveryService {
16
+ discoveryService;
17
+ reflector;
18
+ logger = new Logger(ExtensionDiscoveryService_1.name);
19
+ extensions = new Map();
20
+ functionRegistry = new Map();
21
+ constructor(discoveryService, reflector) {
22
+ this.discoveryService = discoveryService;
23
+ this.reflector = reflector;
24
+ }
25
+ onModuleInit() {
26
+ this.discoverExtensions();
27
+ }
28
+ /**
29
+ * Discover all @Extension decorated classes
30
+ */
31
+ discoverExtensions() {
32
+ const providers = this.discoveryService.getProviders();
33
+ for (const wrapper of providers) {
34
+ const { instance, metatype } = wrapper;
35
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
36
+ if (!instance || !metatype)
37
+ continue;
38
+ const extensionMeta = this.reflector.get(EXTENSION_METADATA, metatype);
39
+ if (!extensionMeta)
40
+ continue;
41
+ this.logger.log(`Discovered extension: ${extensionMeta.name}`);
42
+ // Discover functions on this extension
43
+ const functions = this.discoverFunctions(instance, metatype, extensionMeta.name);
44
+ const metadata = {
45
+ name: extensionMeta.name,
46
+ systemVersion: extensionMeta.systemVersion ?? "v1",
47
+ exclusive: extensionMeta.exclusive ?? false,
48
+ description: extensionMeta.description,
49
+ instance,
50
+ functions,
51
+ };
52
+ this.extensions.set(extensionMeta.name, metadata);
53
+ // Register functions globally for routing
54
+ for (const func of functions) {
55
+ this.functionRegistry.set(func.fullName, func);
56
+ this.logger.debug(`Registered function: ${func.fullName}`);
57
+ }
58
+ }
59
+ }
60
+ /**
61
+ * Discover @Function decorated methods on an extension class
62
+ */
63
+ discoverFunctions(instance, metatype, extensionName) {
64
+ const functionKeys = Reflect.getMetadata(FUNCTIONS_METADATA, metatype) ?? [];
65
+ const results = [];
66
+ for (const methodName of functionKeys) {
67
+ const funcMeta = Reflect.getMetadata(FUNCTION_METADATA, metatype, methodName);
68
+ if (!funcMeta)
69
+ continue;
70
+ // Get schema metadata
71
+ const inputSchema = Reflect.getMetadata(INPUT_SCHEMA_METADATA, metatype, methodName);
72
+ const outputSchema = Reflect.getMetadata(OUTPUT_SCHEMA_METADATA, metatype, methodName);
73
+ const description = Reflect.getMetadata(DESCRIPTION_METADATA, metatype, methodName) ?? funcMeta.description;
74
+ // Get parameter metadata for injection
75
+ const paramMeta = Reflect.getMetadata(PARAM_METADATA, metatype, methodName) ?? [];
76
+ // Build full method name for routing
77
+ const fullName = `extension.${extensionName}.${funcMeta.name}`;
78
+ // Convert schemas to JSON Schema
79
+ const inputJsonSchema = inputSchema
80
+ ? zodToJsonSchema(inputSchema, { $refStrategy: "none" })
81
+ : undefined;
82
+ const outputJsonSchema = outputSchema
83
+ ? zodToJsonSchema(outputSchema, { $refStrategy: "none" })
84
+ : undefined;
85
+ // Create bound handler with parameter injection
86
+ const handler = this.createHandler(instance, methodName, paramMeta, inputSchema, outputSchema);
87
+ const funcMetadata = {
88
+ name: funcMeta.name,
89
+ fullName,
90
+ methodName,
91
+ handler,
92
+ };
93
+ if (description) {
94
+ funcMetadata.description = description;
95
+ }
96
+ if (inputSchema) {
97
+ funcMetadata.inputSchema = inputSchema;
98
+ }
99
+ if (outputSchema) {
100
+ funcMetadata.outputSchema = outputSchema;
101
+ }
102
+ if (inputJsonSchema) {
103
+ funcMetadata.inputJsonSchema = inputJsonSchema;
104
+ }
105
+ if (outputJsonSchema) {
106
+ funcMetadata.outputJsonSchema = outputJsonSchema;
107
+ }
108
+ results.push(funcMetadata);
109
+ }
110
+ return results;
111
+ }
112
+ /**
113
+ * Create a handler function with parameter injection and validation
114
+ */
115
+ createHandler(instance, methodName, paramMeta, inputSchema, outputSchema) {
116
+ const method = instance[methodName];
117
+ return async (ctx, params) => {
118
+ // Validate input if schema is defined
119
+ let validatedParams = params;
120
+ if (inputSchema) {
121
+ validatedParams = inputSchema.parse(params);
122
+ }
123
+ // Build arguments based on parameter decorators
124
+ const args = [];
125
+ // Sort by index to maintain order
126
+ const sortedParams = [...paramMeta].sort((a, b) => a.index - b.index);
127
+ for (const param of sortedParams) {
128
+ switch (param.type) {
129
+ case FunctionParamType.CTX:
130
+ args[param.index] = ctx;
131
+ break;
132
+ case FunctionParamType.INPUT:
133
+ args[param.index] = validatedParams;
134
+ break;
135
+ case FunctionParamType.BODY:
136
+ args[param.index] = { context: ctx, params: validatedParams };
137
+ break;
138
+ }
139
+ }
140
+ // If no parameter decorators, use default order: (ctx, params)
141
+ if (sortedParams.length === 0) {
142
+ args.push(ctx, validatedParams);
143
+ }
144
+ // Call the method
145
+ const result = await method.apply(instance, args);
146
+ // Validate output if schema is defined
147
+ if (outputSchema) {
148
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
149
+ return outputSchema.parse(result);
150
+ }
151
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
152
+ return result;
153
+ };
154
+ }
155
+ /**
156
+ * Get all discovered extensions
157
+ */
158
+ getExtensions() {
159
+ return Array.from(this.extensions.values());
160
+ }
161
+ /**
162
+ * Get a specific extension by name
163
+ */
164
+ getExtension(name) {
165
+ return this.extensions.get(name);
166
+ }
167
+ /**
168
+ * Get a function by its full name (e.g., "extension.calendar.getAvailability")
169
+ */
170
+ getFunction(fullName) {
171
+ return this.functionRegistry.get(fullName);
172
+ }
173
+ /**
174
+ * Get all registered functions
175
+ */
176
+ getAllFunctions() {
177
+ return Array.from(this.functionRegistry.values());
178
+ }
179
+ /**
180
+ * Check if any extensions are registered
181
+ */
182
+ hasExtensions() {
183
+ return this.extensions.size > 0;
184
+ }
185
+ };
186
+ ExtensionDiscoveryService = ExtensionDiscoveryService_1 = __decorate([
187
+ Injectable(),
188
+ __metadata("design:paramtypes", [DiscoveryService,
189
+ Reflector])
190
+ ], ExtensionDiscoveryService);
191
+ export { ExtensionDiscoveryService };
192
+ //# sourceMappingURL=extension-discovery.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-discovery.service.js","sourceRoot":"","sources":["../../src/discovery/extension-discovery.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { ExtensionDiscoveryService } from "./extension-discovery.service.js";
2
+ export type { ExtensionMetadata, FunctionMetadata } from "./metadata.interface.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { ExtensionDiscoveryService } from "./extension-discovery.service.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { z } from "zod";
2
+ /**
3
+ * Metadata for a discovered extension
4
+ */
5
+ export interface ExtensionMetadata {
6
+ /** Extension name */
7
+ name: string;
8
+ /** System version (e.g., "v1") */
9
+ systemVersion: string;
10
+ /** Whether this is an exclusive extension */
11
+ exclusive: boolean;
12
+ /** Extension description */
13
+ description?: string;
14
+ /** Class instance */
15
+ instance: unknown;
16
+ /** Discovered functions */
17
+ functions: FunctionMetadata[];
18
+ }
19
+ /**
20
+ * Metadata for a discovered function
21
+ */
22
+ export interface FunctionMetadata {
23
+ /** Function name (e.g., "getAvailability" or "booking.create") */
24
+ name: string;
25
+ /** Full method name for routing (e.g., "extension.calendar.getAvailability") */
26
+ fullName: string;
27
+ /** Method name on the class */
28
+ methodName: string | symbol;
29
+ /** Function description */
30
+ description?: string;
31
+ /** Input schema (Zod) */
32
+ inputSchema?: z.ZodSchema;
33
+ /** Output schema (Zod) */
34
+ outputSchema?: z.ZodSchema;
35
+ /** JSON Schema for input */
36
+ inputJsonSchema?: Record<string, unknown>;
37
+ /** JSON Schema for output */
38
+ outputJsonSchema?: Record<string, unknown>;
39
+ /** Bound handler function */
40
+ handler: (ctx: unknown, params: unknown) => Promise<unknown>;
41
+ }
42
+ //# sourceMappingURL=metadata.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.interface.d.ts","sourceRoot":"","sources":["../../src/discovery/metadata.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,2BAA2B;IAC3B,SAAS,EAAE,gBAAgB,EAAE,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,WAAW,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IAC1B,0BAA0B;IAC1B,YAAY,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IAC3B,4BAA4B;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,6BAA6B;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,6BAA6B;IAC7B,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=metadata.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.interface.js","sourceRoot":"","sources":["../../src/discovery/metadata.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export * from "./signature.guard.js";
2
+ export * from "./signature.middleware.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guards/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./signature.guard.js";
2
+ export * from "./signature.middleware.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/guards/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { CanActivate, ExecutionContext, type Type } from "@nestjs/common";
2
+ import { type ChannelAppModuleOptions } from "../nestjs/types.js";
3
+ /**
4
+ * Header name for the signature
5
+ */
6
+ export declare const SIGNATURE_HEADER = "x-signature";
7
+ /**
8
+ * Verify HMAC-SHA256 signature from ch-app-store
9
+ *
10
+ * Algorithm:
11
+ * 1. Decode signing key from hex format
12
+ * 2. Create HMAC-SHA256 hash of the raw request body
13
+ * 3. Encode result as Base64
14
+ * 4. Compare with X-Signature header using timing-safe comparison
15
+ *
16
+ * @param signature The X-Signature header value
17
+ * @param signingKey The hex-encoded signing key (from app secret or dedicated signing key)
18
+ * @param body Raw request body bytes
19
+ * @returns true if signature is valid
20
+ */
21
+ export declare function verifySignature(signature: string, signingKey: string, body: Buffer): boolean;
22
+ /**
23
+ * NestJS Guard for verifying X-Signature header from ch-app-store
24
+ *
25
+ * This guard verifies that incoming requests are authentically from ch-app-store
26
+ * by validating the HMAC-SHA256 signature in the X-Signature header.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * // Apply to a specific controller
31
+ * @UseGuards(SignatureGuard)
32
+ * @Controller('functions')
33
+ * export class FunctionsController { ... }
34
+ *
35
+ * // Or apply globally in module
36
+ * @Module({
37
+ * providers: [
38
+ * { provide: APP_GUARD, useClass: SignatureGuard },
39
+ * ],
40
+ * })
41
+ * export class AppModule {}
42
+ * ```
43
+ *
44
+ * IMPORTANT: For this guard to work, you must configure raw body parsing:
45
+ * ```typescript
46
+ * // main.ts
47
+ * app.useBodyParser('raw', { type: 'application/json' });
48
+ * ```
49
+ *
50
+ * Or use the `SignatureMiddleware` which handles body buffering automatically.
51
+ */
52
+ export declare class SignatureGuard implements CanActivate {
53
+ private readonly options;
54
+ private readonly logger;
55
+ constructor(options: ChannelAppModuleOptions);
56
+ canActivate(context: ExecutionContext): boolean;
57
+ }
58
+ /**
59
+ * Factory function to create SignatureGuard with custom options
60
+ * Useful when you need to customize the guard behavior
61
+ */
62
+ export declare function createSignatureGuard(options?: {
63
+ skipForRoutes?: string[];
64
+ }): Type<CanActivate>;
65
+ //# sourceMappingURL=signature.guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature.guard.d.ts","sourceRoot":"","sources":["../../src/guards/signature.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,gBAAgB,EAIhB,KAAK,IAAI,EACV,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAuB,KAAK,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAEvF;;GAEG;AACH,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAE9C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAyB5F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBACa,cAAe,YAAW,WAAW;IAK9C,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;gBAIvC,OAAO,EAAE,uBAAuB;IAGnD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;CA0ChD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,WAAW,CAAC,CAiB9F"}
@@ -0,0 +1,156 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ var SignatureGuard_1;
14
+ import { Injectable, UnauthorizedException, Logger, Inject, } from "@nestjs/common";
15
+ import { createHmac, timingSafeEqual } from "crypto";
16
+ import { CHANNEL_APP_OPTIONS } from "../nestjs/types.js";
17
+ /**
18
+ * Header name for the signature
19
+ */
20
+ export const SIGNATURE_HEADER = "x-signature";
21
+ /**
22
+ * Verify HMAC-SHA256 signature from ch-app-store
23
+ *
24
+ * Algorithm:
25
+ * 1. Decode signing key from hex format
26
+ * 2. Create HMAC-SHA256 hash of the raw request body
27
+ * 3. Encode result as Base64
28
+ * 4. Compare with X-Signature header using timing-safe comparison
29
+ *
30
+ * @param signature The X-Signature header value
31
+ * @param signingKey The hex-encoded signing key (from app secret or dedicated signing key)
32
+ * @param body Raw request body bytes
33
+ * @returns true if signature is valid
34
+ */
35
+ export function verifySignature(signature, signingKey, body) {
36
+ try {
37
+ // Decode the signing key from hex format
38
+ const keyBuffer = Buffer.from(signingKey, "hex");
39
+ // Create HMAC-SHA256 hash
40
+ const hmac = createHmac("sha256", keyBuffer);
41
+ hmac.update(body);
42
+ // Get Base64 encoded signature
43
+ const computedSignature = hmac.digest("base64");
44
+ // Use timing-safe comparison to prevent timing attacks
45
+ const signatureBuffer = Buffer.from(signature, "utf-8");
46
+ const computedBuffer = Buffer.from(computedSignature, "utf-8");
47
+ // Buffers must be same length for timingSafeEqual
48
+ if (signatureBuffer.length !== computedBuffer.length) {
49
+ return false;
50
+ }
51
+ return timingSafeEqual(signatureBuffer, computedBuffer);
52
+ }
53
+ catch {
54
+ return false;
55
+ }
56
+ }
57
+ /**
58
+ * NestJS Guard for verifying X-Signature header from ch-app-store
59
+ *
60
+ * This guard verifies that incoming requests are authentically from ch-app-store
61
+ * by validating the HMAC-SHA256 signature in the X-Signature header.
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * // Apply to a specific controller
66
+ * @UseGuards(SignatureGuard)
67
+ * @Controller('functions')
68
+ * export class FunctionsController { ... }
69
+ *
70
+ * // Or apply globally in module
71
+ * @Module({
72
+ * providers: [
73
+ * { provide: APP_GUARD, useClass: SignatureGuard },
74
+ * ],
75
+ * })
76
+ * export class AppModule {}
77
+ * ```
78
+ *
79
+ * IMPORTANT: For this guard to work, you must configure raw body parsing:
80
+ * ```typescript
81
+ * // main.ts
82
+ * app.useBodyParser('raw', { type: 'application/json' });
83
+ * ```
84
+ *
85
+ * Or use the `SignatureMiddleware` which handles body buffering automatically.
86
+ */
87
+ let SignatureGuard = SignatureGuard_1 = class SignatureGuard {
88
+ options;
89
+ logger = new Logger(SignatureGuard_1.name);
90
+ constructor(options) {
91
+ this.options = options;
92
+ }
93
+ canActivate(context) {
94
+ // Skip if signature verification is disabled
95
+ if (this.options.skipSignatureVerification) {
96
+ return true;
97
+ }
98
+ const request = context.switchToHttp().getRequest();
99
+ const signature = request.headers[SIGNATURE_HEADER];
100
+ if (!signature) {
101
+ this.logger.warn("Missing X-Signature header");
102
+ throw new UnauthorizedException("Missing X-Signature header");
103
+ }
104
+ // Get the signing key (use signingKey if provided, otherwise derive from appSecret)
105
+ const signingKey = this.options.signingKey ?? this.options.appSecret;
106
+ if (!signingKey) {
107
+ this.logger.error("No signing key configured");
108
+ throw new UnauthorizedException("Signature verification not configured");
109
+ }
110
+ // Get raw body - requires raw body middleware
111
+ const rawBody = request.rawBody;
112
+ if (!rawBody) {
113
+ this.logger.error("Raw body not available. Ensure raw body middleware is configured.");
114
+ throw new UnauthorizedException("Cannot verify signature - raw body not available");
115
+ }
116
+ const isValid = verifySignature(signature, signingKey, rawBody);
117
+ if (!isValid) {
118
+ this.logger.warn("Invalid signature");
119
+ throw new UnauthorizedException("Invalid signature");
120
+ }
121
+ if (this.options.debug) {
122
+ this.logger.debug("Signature verified successfully");
123
+ }
124
+ return true;
125
+ }
126
+ };
127
+ SignatureGuard = SignatureGuard_1 = __decorate([
128
+ Injectable(),
129
+ __param(0, Inject(CHANNEL_APP_OPTIONS)),
130
+ __metadata("design:paramtypes", [Object])
131
+ ], SignatureGuard);
132
+ export { SignatureGuard };
133
+ /**
134
+ * Factory function to create SignatureGuard with custom options
135
+ * Useful when you need to customize the guard behavior
136
+ */
137
+ export function createSignatureGuard(options) {
138
+ let ConfigurableSignatureGuard = class ConfigurableSignatureGuard extends SignatureGuard {
139
+ canActivate(context) {
140
+ // Check if route should be skipped
141
+ if (options?.skipForRoutes) {
142
+ const request = context.switchToHttp().getRequest();
143
+ const path = request.path || request.url;
144
+ if (options.skipForRoutes.some((route) => path.startsWith(route))) {
145
+ return true;
146
+ }
147
+ }
148
+ return super.canActivate(context);
149
+ }
150
+ };
151
+ ConfigurableSignatureGuard = __decorate([
152
+ Injectable()
153
+ ], ConfigurableSignatureGuard);
154
+ return ConfigurableSignatureGuard;
155
+ }
156
+ //# sourceMappingURL=signature.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature.guard.js","sourceRoot":"","sources":["../../src/guards/signature.guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { type NestMiddleware } from "@nestjs/common";
2
+ import type { Request, Response, NextFunction } from "express";
3
+ /**
4
+ * Extend Express Request to include rawBody
5
+ */
6
+ declare global {
7
+ namespace Express {
8
+ interface Request {
9
+ rawBody?: Buffer;
10
+ }
11
+ }
12
+ }
13
+ /**
14
+ * Middleware to capture raw request body for signature verification
15
+ *
16
+ * This middleware reads the raw body and stores it in `request.rawBody`
17
+ * while still allowing the body to be parsed by subsequent middlewares.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * // Apply in NestJS module
22
+ * export class AppModule implements NestModule {
23
+ * configure(consumer: MiddlewareConsumer) {
24
+ * consumer
25
+ * .apply(SignatureMiddleware)
26
+ * .forRoutes('functions');
27
+ * }
28
+ * }
29
+ * ```
30
+ *
31
+ * Or configure globally in main.ts:
32
+ * ```typescript
33
+ * // main.ts - Alternative approach with express
34
+ * import express from 'express';
35
+ *
36
+ * app.use(express.json({
37
+ * verify: (req, res, buf) => {
38
+ * req.rawBody = buf;
39
+ * },
40
+ * }));
41
+ * ```
42
+ */
43
+ export declare class SignatureMiddleware implements NestMiddleware {
44
+ use(req: Request, _res: Response, next: NextFunction): void;
45
+ }
46
+ /**
47
+ * Express middleware function for raw body capture
48
+ * Use this if you prefer a function-based middleware
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * // main.ts
53
+ * app.use('/functions', rawBodyMiddleware);
54
+ * ```
55
+ */
56
+ export declare function rawBodyMiddleware(req: Request, _res: Response, next: NextFunction): void;
57
+ /**
58
+ * Create express.json() options with raw body capture
59
+ * This is the recommended approach for signature verification
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * // main.ts
64
+ * import express from 'express';
65
+ *
66
+ * const app = await NestFactory.create(AppModule, {
67
+ * bodyParser: false, // Disable default body parser
68
+ * });
69
+ *
70
+ * app.use(express.json(jsonWithRawBody()));
71
+ * ```
72
+ */
73
+ export declare function jsonWithRawBody(): {
74
+ verify: (req: Request, res: Response, buf: Buffer) => void;
75
+ };
76
+ //# sourceMappingURL=signature.middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature.middleware.d.ts","sourceRoot":"","sources":["../../src/guards/signature.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE/D;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB;KACF;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBACa,mBAAoB,YAAW,cAAc;IACxD,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;CAqB5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAmBxF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,IAAI;IACjC,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5D,CAMA"}