@prauga/flexdoc-backend 2.1.0 → 2.3.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 (49) hide show
  1. package/README.md +227 -227
  2. package/dist/auth.d.ts +11 -0
  3. package/dist/auth.js +99 -0
  4. package/dist/auth.js.map +1 -0
  5. package/dist/auth.test.d.ts +1 -0
  6. package/dist/auth.test.js +57 -0
  7. package/dist/auth.test.js.map +1 -0
  8. package/dist/flexdoc.module.test.js +9 -0
  9. package/dist/flexdoc.module.test.js.map +1 -1
  10. package/dist/framework-adapters.d.ts +3 -0
  11. package/dist/framework-adapters.js +34 -3
  12. package/dist/framework-adapters.js.map +1 -1
  13. package/dist/framework-adapters.test.js +44 -13
  14. package/dist/framework-adapters.test.js.map +1 -1
  15. package/dist/hono-adapter.d.ts +12 -0
  16. package/dist/hono-adapter.js +63 -0
  17. package/dist/hono-adapter.js.map +1 -0
  18. package/dist/hono-adapter.test.d.ts +1 -0
  19. package/dist/hono-adapter.test.js +82 -0
  20. package/dist/hono-adapter.test.js.map +1 -0
  21. package/dist/index.d.ts +3 -1
  22. package/dist/index.js +4 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/interfaces.d.ts +5 -0
  25. package/dist/renderer/flexdoc.standalone.css +1 -1
  26. package/dist/renderer/flexdoc.standalone.js +49 -197
  27. package/dist/renderer-assets.d.ts +1 -0
  28. package/dist/renderer-assets.js +6 -2
  29. package/dist/renderer-assets.js.map +1 -1
  30. package/dist/setup.js +10 -62
  31. package/dist/setup.js.map +1 -1
  32. package/dist/setup.test.js +6 -1
  33. package/dist/setup.test.js.map +1 -1
  34. package/dist/template.d.ts +1 -0
  35. package/dist/template.js +44 -43
  36. package/dist/template.js.map +1 -1
  37. package/dist/template.test.js +8 -0
  38. package/dist/template.test.js.map +1 -1
  39. package/dist/tsconfig.tsbuildinfo +1 -1
  40. package/package.json +34 -34
  41. package/dist/templates/code-examples.njk +0 -106
  42. package/dist/templates/content.njk +0 -272
  43. package/dist/templates/footer.njk +0 -38
  44. package/dist/templates/header.njk +0 -57
  45. package/dist/templates/layout.njk +0 -647
  46. package/dist/templates/parameters.njk +0 -64
  47. package/dist/templates/request-body.njk +0 -63
  48. package/dist/templates/responses.njk +0 -78
  49. package/dist/templates/sidebar.njk +0 -117
package/README.md CHANGED
@@ -1,227 +1,227 @@
1
- # FlexDoc Backend
2
-
3
- [![npm version](https://img.shields.io/npm/v/@prauga/flexdoc-backend.svg)](https://www.npmjs.com/package/@prauga/flexdoc-backend)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
-
6
- The backend package for FlexDoc, a modern, customizable OpenAPI documentation generator that creates beautiful API documentation.
7
-
8
- ## Screenshots
9
-
10
- ### Light Mode
11
-
12
- ![FlexDoc Light Mode](./images/flexdoc-light.png)
13
-
14
- ### Dark Mode
15
-
16
- ![FlexDoc Dark Mode](./images/flexdoc-dark.png)
17
-
18
- ## Features
19
-
20
- - **Modern UI**: Clean, responsive interface with dark mode support
21
- - **Customizable**: Easily customize colors, typography, and layout
22
- - **Interactive**: Test API endpoints directly from the documentation
23
- - **Framework Agnostic**: Works with any JavaScript framework
24
- - **OpenAPI Compatible**: Supports OpenAPI 3.0 specifications
25
-
26
- ## Installation
27
-
28
- ```bash
29
- npm install @prauga/flexdoc-backend
30
- ```
31
-
32
- ## Usage
33
-
34
- ### Basic Usage
35
-
36
- ```typescript
37
- import { FlexDoc } from '@prauga/flexdoc-backend';
38
- import { OpenAPIObject } from '@nestjs/swagger';
39
-
40
- // Create a new FlexDoc instance with your OpenAPI spec
41
- const flexdoc = new FlexDoc({
42
- spec: yourOpenAPISpec as OpenAPIObject,
43
- title: 'My API Documentation',
44
- description: 'Documentation for my awesome API',
45
- });
46
-
47
- // Generate HTML documentation
48
- const html = flexdoc.generateHTML();
49
-
50
- // Serve the documentation
51
- app.get('/api/docs', (req, res) => {
52
- res.send(html);
53
- });
54
- ```
55
-
56
- ### Configuration Options
57
-
58
- FlexDoc is highly customizable through the `FlexDocOptions` interface:
59
-
60
- ```typescript
61
- import { FlexDoc, FlexDocOptions } from '@prauga/flexdoc-backend';
62
-
63
- const options: FlexDocOptions = {
64
- // Required
65
- spec: yourOpenAPISpec,
66
-
67
- // Basic metadata
68
- title: 'My API Documentation',
69
- description: 'Documentation for my awesome API',
70
-
71
- // Theme configuration
72
- themeConfig: {
73
- colors: {
74
- primary: {
75
- main: '#3b82f6',
76
- light: '#eff6ff',
77
- dark: '#2563eb',
78
- },
79
- // Additional color options...
80
- },
81
- typography: {
82
- fontFamily: 'Inter, system-ui, sans-serif',
83
- fontSize: '16px',
84
- // Additional typography options...
85
- },
86
- },
87
-
88
- // Footer customization
89
- footer: {
90
- copyright: '© 2025 My Company',
91
- links: [
92
- {
93
- text: 'Terms',
94
- url: '/terms',
95
- icon: 'file-text', // Optional Lucide icon name
96
- },
97
- {
98
- text: 'Privacy',
99
- url: '/privacy',
100
- },
101
- ],
102
- },
103
-
104
- // Additional options...
105
- };
106
-
107
- const flexdoc = new FlexDoc(options);
108
- ```
109
-
110
- ### Framework Integration Examples
111
-
112
- #### NestJS
113
-
114
- ```typescript
115
- import { NestFactory } from '@nestjs/core';
116
- import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
117
- import { FlexDoc } from '@prauga/flexdoc-backend';
118
- import { AppModule } from './app.module';
119
-
120
- async function bootstrap() {
121
- const app = await NestFactory.create(AppModule);
122
-
123
- // Create OpenAPI spec with Swagger
124
- const config = new DocumentBuilder()
125
- .setTitle('My API')
126
- .setDescription('My API description')
127
- .setVersion('1.0')
128
- .build();
129
- const document = SwaggerModule.createDocument(app, config);
130
-
131
- // Create FlexDoc instance
132
- const flexdoc = new FlexDoc({
133
- spec: document,
134
- title: 'My API Documentation',
135
- description: 'Documentation for my awesome API',
136
- footer: {
137
- copyright: '© 2025 My Company',
138
- },
139
- });
140
-
141
- // Serve FlexDoc at /api/docs
142
- app.use('/api/docs', (req, res) => {
143
- res.send(flexdoc.generateHTML());
144
- });
145
-
146
- await app.listen(3000);
147
- }
148
- bootstrap();
149
- ```
150
-
151
- #### Express
152
-
153
- ```typescript
154
- import express from 'express';
155
- import { FlexDoc } from '@prauga/flexdoc-backend';
156
- import swaggerJsdoc from 'swagger-jsdoc';
157
-
158
- const app = express();
159
-
160
- // Generate OpenAPI spec
161
- const options = {
162
- definition: {
163
- openapi: '3.0.0',
164
- info: {
165
- title: 'My API',
166
- version: '1.0.0',
167
- },
168
- },
169
- apis: ['./src/routes/*.js'],
170
- };
171
- const openapiSpec = swaggerJsdoc(options);
172
-
173
- // Create FlexDoc instance
174
- const flexdoc = new FlexDoc({
175
- spec: openapiSpec,
176
- title: 'My API Documentation',
177
- });
178
-
179
- // Serve FlexDoc
180
- app.get('/api/docs', (req, res) => {
181
- res.send(flexdoc.generateHTML());
182
- });
183
-
184
- app.listen(3000);
185
- ```
186
-
187
- ## API Reference
188
-
189
- ### `FlexDoc` Class
190
-
191
- The main class for generating API documentation.
192
-
193
- #### Constructor
194
-
195
- ```typescript
196
- constructor(options: FlexDocOptions)
197
- ```
198
-
199
- #### Methods
200
-
201
- - `generateHTML()`: Generates the HTML documentation
202
- - `getOpenAPISpec()`: Returns the processed OpenAPI specification
203
-
204
- ### `FlexDocOptions` Interface
205
-
206
- Configuration options for FlexDoc:
207
-
208
- | Property | Type | Description |
209
- | -------------- | ------------------------------- | -------------------------------- |
210
- | `spec` | `OpenAPIObject` | The OpenAPI specification object |
211
- | `title` | `string` | Documentation title |
212
- | `description` | `string` | Documentation description |
213
- | `themeConfig` | `ThemeConfig` | Theme configuration |
214
- | `footer` | `FooterConfig` | Footer configuration |
215
- | `favicon` | `string` | URL to favicon |
216
- | `customCss` | `string` | Custom CSS to inject |
217
- | `customJs` | `string` | Custom JavaScript to inject |
218
- | `defaultTheme` | `'light' \| 'dark' \| 'system'` | Default theme mode |
219
-
220
- ## Contributing
221
-
222
- Contributions are welcome! Please feel free to submit a Pull Request.
223
-
224
- ## License
225
-
226
- This project is licensed under the MIT License - see the LICENSE file for details.
227
-
1
+ # FlexDoc Backend
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@prauga/flexdoc-backend.svg)](https://www.npmjs.com/package/@prauga/flexdoc-backend)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ The backend package for FlexDoc, a modern, customizable OpenAPI documentation generator that creates beautiful API documentation.
7
+
8
+ ## Screenshots
9
+
10
+ ### Light Mode
11
+
12
+ ![FlexDoc Light Mode](./images/flexdoc-light.png)
13
+
14
+ ### Dark Mode
15
+
16
+ ![FlexDoc Dark Mode](./images/flexdoc-dark.png)
17
+
18
+ ## Features
19
+
20
+ - **Modern UI**: Clean, responsive interface with dark mode support
21
+ - **Customizable**: Easily customize colors, typography, and layout
22
+ - **Interactive**: Test API endpoints directly from the documentation
23
+ - **Framework Agnostic**: Works with any JavaScript framework
24
+ - **OpenAPI Compatible**: Supports OpenAPI 3.0 specifications
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ npm install @prauga/flexdoc-backend
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ### Basic Usage
35
+
36
+ ```typescript
37
+ import { FlexDoc } from '@prauga/flexdoc-backend';
38
+ import { OpenAPIObject } from '@nestjs/swagger';
39
+
40
+ // Create a new FlexDoc instance with your OpenAPI spec
41
+ const flexdoc = new FlexDoc({
42
+ spec: yourOpenAPISpec as OpenAPIObject,
43
+ title: 'My API Documentation',
44
+ description: 'Documentation for my awesome API',
45
+ });
46
+
47
+ // Generate HTML documentation
48
+ const html = flexdoc.generateHTML();
49
+
50
+ // Serve the documentation
51
+ app.get('/api/docs', (req, res) => {
52
+ res.send(html);
53
+ });
54
+ ```
55
+
56
+ ### Configuration Options
57
+
58
+ FlexDoc is highly customizable through the `FlexDocOptions` interface:
59
+
60
+ ```typescript
61
+ import { FlexDoc, FlexDocOptions } from '@prauga/flexdoc-backend';
62
+
63
+ const options: FlexDocOptions = {
64
+ // Required
65
+ spec: yourOpenAPISpec,
66
+
67
+ // Basic metadata
68
+ title: 'My API Documentation',
69
+ description: 'Documentation for my awesome API',
70
+
71
+ // Theme configuration
72
+ themeConfig: {
73
+ colors: {
74
+ primary: {
75
+ main: '#3b82f6',
76
+ light: '#eff6ff',
77
+ dark: '#2563eb',
78
+ },
79
+ // Additional color options...
80
+ },
81
+ typography: {
82
+ fontFamily: 'Inter, system-ui, sans-serif',
83
+ fontSize: '16px',
84
+ // Additional typography options...
85
+ },
86
+ },
87
+
88
+ // Footer customization
89
+ footer: {
90
+ copyright: '© 2025 My Company',
91
+ links: [
92
+ {
93
+ text: 'Terms',
94
+ url: '/terms',
95
+ icon: 'file-text', // Optional Lucide icon name
96
+ },
97
+ {
98
+ text: 'Privacy',
99
+ url: '/privacy',
100
+ },
101
+ ],
102
+ },
103
+
104
+ // Additional options...
105
+ };
106
+
107
+ const flexdoc = new FlexDoc(options);
108
+ ```
109
+
110
+ ### Framework Integration Examples
111
+
112
+ #### NestJS
113
+
114
+ ```typescript
115
+ import { NestFactory } from '@nestjs/core';
116
+ import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
117
+ import { FlexDoc } from '@prauga/flexdoc-backend';
118
+ import { AppModule } from './app.module';
119
+
120
+ async function bootstrap() {
121
+ const app = await NestFactory.create(AppModule);
122
+
123
+ // Create OpenAPI spec with Swagger
124
+ const config = new DocumentBuilder()
125
+ .setTitle('My API')
126
+ .setDescription('My API description')
127
+ .setVersion('1.0')
128
+ .build();
129
+ const document = SwaggerModule.createDocument(app, config);
130
+
131
+ // Create FlexDoc instance
132
+ const flexdoc = new FlexDoc({
133
+ spec: document,
134
+ title: 'My API Documentation',
135
+ description: 'Documentation for my awesome API',
136
+ footer: {
137
+ copyright: '© 2025 My Company',
138
+ },
139
+ });
140
+
141
+ // Serve FlexDoc at /api/docs
142
+ app.use('/api/docs', (req, res) => {
143
+ res.send(flexdoc.generateHTML());
144
+ });
145
+
146
+ await app.listen(3000);
147
+ }
148
+ bootstrap();
149
+ ```
150
+
151
+ #### Express
152
+
153
+ ```typescript
154
+ import express from 'express';
155
+ import { FlexDoc } from '@prauga/flexdoc-backend';
156
+ import swaggerJsdoc from 'swagger-jsdoc';
157
+
158
+ const app = express();
159
+
160
+ // Generate OpenAPI spec
161
+ const options = {
162
+ definition: {
163
+ openapi: '3.0.0',
164
+ info: {
165
+ title: 'My API',
166
+ version: '1.0.0',
167
+ },
168
+ },
169
+ apis: ['./src/routes/*.js'],
170
+ };
171
+ const openapiSpec = swaggerJsdoc(options);
172
+
173
+ // Create FlexDoc instance
174
+ const flexdoc = new FlexDoc({
175
+ spec: openapiSpec,
176
+ title: 'My API Documentation',
177
+ });
178
+
179
+ // Serve FlexDoc
180
+ app.get('/api/docs', (req, res) => {
181
+ res.send(flexdoc.generateHTML());
182
+ });
183
+
184
+ app.listen(3000);
185
+ ```
186
+
187
+ ## API Reference
188
+
189
+ ### `FlexDoc` Class
190
+
191
+ The main class for generating API documentation.
192
+
193
+ #### Constructor
194
+
195
+ ```typescript
196
+ constructor(options: FlexDocOptions)
197
+ ```
198
+
199
+ #### Methods
200
+
201
+ - `generateHTML()`: Generates the HTML documentation
202
+ - `getOpenAPISpec()`: Returns the processed OpenAPI specification
203
+
204
+ ### `FlexDocOptions` Interface
205
+
206
+ Configuration options for FlexDoc:
207
+
208
+ | Property | Type | Description |
209
+ | -------------- | ------------------------------- | -------------------------------- |
210
+ | `spec` | `OpenAPIObject` | The OpenAPI specification object |
211
+ | `title` | `string` | Documentation title |
212
+ | `description` | `string` | Documentation description |
213
+ | `themeConfig` | `ThemeConfig` | Theme configuration |
214
+ | `footer` | `FooterConfig` | Footer configuration |
215
+ | `favicon` | `string` | URL to favicon |
216
+ | `customCss` | `string` | Custom CSS to inject |
217
+ | `customJs` | `string` | Custom JavaScript to inject |
218
+ | `defaultTheme` | `'light' \| 'dark' \| 'system'` | Default theme mode |
219
+
220
+ ## Contributing
221
+
222
+ Contributions are welcome! Please feel free to submit a Pull Request.
223
+
224
+ ## License
225
+
226
+ This project is licensed under the MIT License - see the LICENSE file for details.
227
+
package/dist/auth.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ export interface FlexDocAuthOptions {
2
+ secretKey: string;
3
+ type: 'basic' | 'bearer';
4
+ }
5
+ export interface FlexDocAuthDecision {
6
+ authorized: boolean;
7
+ challenge?: string;
8
+ message?: string;
9
+ }
10
+ export declare function generateFlexDocPassword(username: string, secret: string): string;
11
+ export declare function authorizeFlexDocRequest(authHeader: string | undefined, authOptions: FlexDocAuthOptions): FlexDocAuthDecision;
package/dist/auth.js ADDED
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.generateFlexDocPassword = generateFlexDocPassword;
37
+ exports.authorizeFlexDocRequest = authorizeFlexDocRequest;
38
+ const crypto = __importStar(require("crypto"));
39
+ const jwt = __importStar(require("jsonwebtoken"));
40
+ function generateFlexDocPassword(username, secret) {
41
+ const hmac = crypto.createHmac('sha256', secret);
42
+ hmac.update(username);
43
+ const hash = hmac.digest('base64');
44
+ const basePassword = hash.substring(0, 12);
45
+ let password = basePassword;
46
+ if (!/[A-Z]/.test(password))
47
+ password += 'A';
48
+ if (!/[a-z]/.test(password))
49
+ password += 'a';
50
+ if (!/[0-9]/.test(password))
51
+ password += '1';
52
+ if (!/[^A-Za-z0-9]/.test(password))
53
+ password += '!';
54
+ return password;
55
+ }
56
+ function authorizeFlexDocRequest(authHeader, authOptions) {
57
+ const { type, secretKey } = authOptions;
58
+ if (type === 'basic') {
59
+ if (!authHeader || !authHeader.startsWith('Basic ')) {
60
+ return { authorized: false, challenge: 'Basic', message: 'Authentication required' };
61
+ }
62
+ const credentials = Buffer.from(authHeader.slice('Basic '.length), 'base64').toString('ascii');
63
+ const separatorIndex = credentials.indexOf(':');
64
+ const username = separatorIndex === -1 ? credentials : credentials.slice(0, separatorIndex);
65
+ const password = separatorIndex === -1 ? '' : credentials.slice(separatorIndex + 1);
66
+ if (password !== generateFlexDocPassword(username, secretKey)) {
67
+ return { authorized: false, challenge: 'Basic', message: 'Invalid credentials' };
68
+ }
69
+ return { authorized: true };
70
+ }
71
+ let token;
72
+ if (authHeader?.startsWith('Bearer ')) {
73
+ token = authHeader.slice('Bearer '.length);
74
+ }
75
+ else if (authHeader?.startsWith('Basic ')) {
76
+ const credentials = Buffer.from(authHeader.slice('Basic '.length), 'base64').toString('ascii');
77
+ const separatorIndex = credentials.indexOf(':');
78
+ token = separatorIndex === -1 ? undefined : credentials.slice(separatorIndex + 1);
79
+ }
80
+ if (token) {
81
+ try {
82
+ jwt.verify(token, secretKey);
83
+ return { authorized: true };
84
+ }
85
+ catch {
86
+ return {
87
+ authorized: false,
88
+ challenge: 'Basic realm="Enter token as password"',
89
+ message: 'Invalid or expired token',
90
+ };
91
+ }
92
+ }
93
+ return {
94
+ authorized: false,
95
+ challenge: 'Basic realm="Enter token as password"',
96
+ message: 'Authentication required',
97
+ };
98
+ }
99
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const jwt = __importStar(require("jsonwebtoken"));
37
+ const auth_1 = require("./auth");
38
+ describe('FlexDoc route auth', () => {
39
+ it('validates generated basic-auth credentials', () => {
40
+ const secretKey = 'basic-secret';
41
+ const username = 'alice';
42
+ const password = (0, auth_1.generateFlexDocPassword)(username, secretKey);
43
+ const header = `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`;
44
+ expect((0, auth_1.authorizeFlexDocRequest)(undefined, { type: 'basic', secretKey })).toEqual(expect.objectContaining({ authorized: false, challenge: 'Basic' }));
45
+ expect((0, auth_1.authorizeFlexDocRequest)(header, { type: 'basic', secretKey })).toEqual({ authorized: true });
46
+ });
47
+ it('validates bearer tokens and preserves the password-field fallback', () => {
48
+ const secretKey = 'bearer-secret';
49
+ const token = jwt.sign({ sub: 'docs-user' }, secretKey);
50
+ const bearer = `Bearer ${token}`;
51
+ const basicFallback = `Basic ${Buffer.from(`token:${token}`).toString('base64')}`;
52
+ expect((0, auth_1.authorizeFlexDocRequest)(bearer, { type: 'bearer', secretKey })).toEqual({ authorized: true });
53
+ expect((0, auth_1.authorizeFlexDocRequest)(basicFallback, { type: 'bearer', secretKey })).toEqual({ authorized: true });
54
+ expect((0, auth_1.authorizeFlexDocRequest)('Bearer invalid', { type: 'bearer', secretKey })).toEqual(expect.objectContaining({ authorized: false, message: 'Invalid or expired token' }));
55
+ });
56
+ });
57
+ //# sourceMappingURL=auth.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.test.js","sourceRoot":"","sources":["../src/auth.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAAoC;AACpC,iCAGgB;AAEhB,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,SAAS,GAAG,cAAc,CAAC;QACjC,MAAM,QAAQ,GAAG,OAAO,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAA,8BAAuB,EAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAEpF,MAAM,CAAC,IAAA,8BAAuB,EAAC,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,CAC9E,MAAM,CAAC,gBAAgB,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CACnE,CAAC;QACF,MAAM,CAAC,IAAA,8BAAuB,EAAC,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IACtG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,SAAS,GAAG,eAAe,CAAC;QAClC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE,SAAS,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,UAAU,KAAK,EAAE,CAAC;QACjC,MAAM,aAAa,GAAG,SAAS,MAAM,CAAC,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAElF,MAAM,CAAC,IAAA,8BAAuB,EAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QACrG,MAAM,CAAC,IAAA,8BAAuB,EAAC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5G,MAAM,CAAC,IAAA,8BAAuB,EAAC,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,CACtF,MAAM,CAAC,gBAAgB,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC,CACpF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -2,6 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const flexdoc_module_1 = require("./flexdoc.module");
4
4
  const setup_1 = require("./setup");
5
+ jest.mock('@nestjs/common', () => ({
6
+ Module: () => (target) => target,
7
+ Inject: () => () => undefined,
8
+ Injectable: () => (target) => target,
9
+ }));
10
+ jest.mock('@nestjs/core', () => ({
11
+ HttpAdapterHost: class HttpAdapterHost {
12
+ },
13
+ }));
5
14
  jest.mock('./setup', () => ({
6
15
  setupFlexDoc: jest.fn(),
7
16
  }));