hi-secure 1.0.4 → 1.0.6
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/package.json +1 -1
- package/src/core/HiSecure.ts +12 -849
- package/src/core/useSecure.ts +37 -149
- package/src/index.ts +11 -27
- package/src/managers/ValidatorManager.ts +138 -138
- package/src/utils/normalizeOptions.ts +13 -12
package/src/core/useSecure.ts
CHANGED
|
@@ -1,166 +1,54 @@
|
|
|
1
|
-
// import { normalizeOptions } from "../utils/normalizeOptions.js";
|
|
2
|
-
// import { HiSecure } from "./HiSecure.js";
|
|
3
|
-
|
|
4
|
-
// export function useSecure(engine: HiSecure, input?: any) {
|
|
5
|
-
// if (!engine.isInitialized()) {
|
|
6
|
-
// throw new Error("HiSecure must be initialized before using .use()");
|
|
7
|
-
// }
|
|
8
|
-
|
|
9
|
-
// const options = normalizeOptions(input);
|
|
10
|
-
// const chain: any[] = [];
|
|
11
|
-
|
|
12
|
-
// // JSON
|
|
13
|
-
// if (options.json.enabled) {
|
|
14
|
-
// chain.push(engine.jsonManager.middleware(options.json.options));
|
|
15
|
-
// chain.push(engine.jsonManager.urlencoded());
|
|
16
|
-
// }
|
|
17
|
-
|
|
18
|
-
// // CORS
|
|
19
|
-
// if (options.cors.enabled) {
|
|
20
|
-
// chain.push(engine.corsManager.middleware(options.cors.options));
|
|
21
|
-
// }
|
|
22
|
-
|
|
23
|
-
// // Sanitize
|
|
24
|
-
// if (options.sanitize.enabled) {
|
|
25
|
-
// chain.push(engine.sanitizerManager.middleware());
|
|
26
|
-
// }
|
|
27
|
-
|
|
28
|
-
// // Validate
|
|
29
|
-
// if (options.validate.enabled && options.validate.schema) {
|
|
30
|
-
// chain.push(engine.validatorManager.validate(options.validate.schema));
|
|
31
|
-
// }
|
|
32
|
-
|
|
33
|
-
// // Rate Limit
|
|
34
|
-
// if (options.rateLimit.enabled) {
|
|
35
|
-
// chain.push(
|
|
36
|
-
// engine.rateLimitManager.middleware({
|
|
37
|
-
// mode: options.rateLimit.mode ?? undefined,
|
|
38
|
-
// options: options.rateLimit.options ?? undefined
|
|
39
|
-
// })
|
|
40
|
-
// );
|
|
41
|
-
// }
|
|
42
|
-
|
|
43
|
-
// // AUTH
|
|
44
|
-
// if (options.auth.enabled) {
|
|
45
|
-
// if (!engine.authManager) {
|
|
46
|
-
// throw new Error("AuthManager not initialized. Enable auth in config.");
|
|
47
|
-
// }
|
|
48
|
-
|
|
49
|
-
// chain.push(
|
|
50
|
-
// engine.authManager.protect({
|
|
51
|
-
// required: options.auth.required
|
|
52
|
-
// })
|
|
53
|
-
// );
|
|
54
|
-
// }
|
|
55
|
-
|
|
56
|
-
// return chain;
|
|
57
|
-
// }
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
1
|
// src/core/useSecure.ts - SIMPLER VERSION
|
|
62
2
|
// This is now optional since HiSecure class has fluent API
|
|
63
3
|
|
|
64
4
|
|
|
65
|
-
// import { HiSecure } from "./HiSecure.js";
|
|
66
|
-
// import { SecureOptions } from "./types/SecureOptions.js";
|
|
67
|
-
|
|
68
|
-
// /**
|
|
69
|
-
// * @deprecated Use HiSecure.middleware() or fluent API instead
|
|
70
|
-
// */
|
|
71
|
-
// export function useSecure(options?: SecureOptions | "api" | "strict" | "public") {
|
|
72
|
-
// console.warn("⚠ useSecure() is deprecated. Use HiSecure.middleware() or fluent API methods.");
|
|
73
|
-
// return HiSecure.middleware(options);
|
|
74
|
-
// }
|
|
75
|
-
|
|
76
|
-
// /**
|
|
77
|
-
// * Legacy support - route-level security
|
|
78
|
-
// */
|
|
79
|
-
// export function secureRoute(options?: SecureOptions) {
|
|
80
|
-
// const chain: any[] = [];
|
|
81
|
-
|
|
82
|
-
// if (options?.cors) {
|
|
83
|
-
// chain.push(HiSecure.cors(
|
|
84
|
-
// typeof options.cors === 'object' ? options.cors : undefined
|
|
85
|
-
// ));
|
|
86
|
-
// }
|
|
87
|
-
|
|
88
|
-
// if (options?.rateLimit) {
|
|
89
|
-
// chain.push(HiSecure.rateLimit(
|
|
90
|
-
// typeof options.rateLimit === 'object' ? options.rateLimit :
|
|
91
|
-
// options.rateLimit === "strict" ? "strict" : "relaxed"
|
|
92
|
-
// ));
|
|
93
|
-
// }
|
|
94
|
-
|
|
95
|
-
// if (options?.sanitize) {
|
|
96
|
-
// chain.push(HiSecure.sanitize(
|
|
97
|
-
// typeof options.sanitize === 'object' ? options.sanitize : undefined
|
|
98
|
-
// ));
|
|
99
|
-
// }
|
|
100
|
-
|
|
101
|
-
// if (options?.validate) {
|
|
102
|
-
// chain.push(HiSecure.validate(options.validate));
|
|
103
|
-
// }
|
|
104
|
-
|
|
105
|
-
// if (options?.auth) {
|
|
106
|
-
// chain.push(HiSecure.auth(
|
|
107
|
-
// typeof options.auth === 'object' ? options.auth : undefined
|
|
108
|
-
// ));
|
|
109
|
-
// }
|
|
110
|
-
|
|
111
|
-
// return chain;
|
|
112
|
-
// }
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
5
|
import { HiSecure } from "./HiSecure.js";
|
|
118
6
|
import { SecureOptions } from "./types/SecureOptions.js";
|
|
119
7
|
|
|
120
|
-
|
|
121
|
-
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated Use HiSecure.middleware() or fluent API instead
|
|
10
|
+
*/
|
|
11
|
+
export function useSecure(options?: SecureOptions | "api" | "strict" | "public") {
|
|
12
|
+
console.warn("⚠ useSecure() is deprecated. Use HiSecure.middleware() or fluent API methods.");
|
|
13
|
+
return HiSecure.middleware(options);
|
|
14
|
+
}
|
|
122
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Legacy support - route-level security
|
|
18
|
+
*/
|
|
19
|
+
export function secureRoute(options?: SecureOptions) {
|
|
123
20
|
const chain: any[] = [];
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
);
|
|
21
|
+
|
|
22
|
+
if (options?.cors) {
|
|
23
|
+
chain.push(HiSecure.cors(
|
|
24
|
+
typeof options.cors === 'object' ? options.cors : undefined
|
|
25
|
+
));
|
|
130
26
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
} else if (typeof rl === "object") {
|
|
138
|
-
chain.push(HiSecure.rateLimit(rl));
|
|
139
|
-
} else {
|
|
140
|
-
chain.push(HiSecure.rateLimit("relaxed"));
|
|
141
|
-
}
|
|
27
|
+
|
|
28
|
+
if (options?.rateLimit) {
|
|
29
|
+
chain.push(HiSecure.rateLimit(
|
|
30
|
+
typeof options.rateLimit === 'object' ? options.rateLimit :
|
|
31
|
+
options.rateLimit === "strict" ? "strict" : "relaxed"
|
|
32
|
+
));
|
|
142
33
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
);
|
|
34
|
+
|
|
35
|
+
if (options?.sanitize) {
|
|
36
|
+
chain.push(HiSecure.sanitize(
|
|
37
|
+
typeof options.sanitize === 'object' ? options.sanitize : undefined
|
|
38
|
+
));
|
|
149
39
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (options.validate) {
|
|
40
|
+
|
|
41
|
+
if (options?.validate) {
|
|
153
42
|
chain.push(HiSecure.validate(options.validate));
|
|
154
43
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
typeof options.auth === "object" ? options.auth : undefined
|
|
161
|
-
)
|
|
162
|
-
);
|
|
44
|
+
|
|
45
|
+
if (options?.auth) {
|
|
46
|
+
chain.push(HiSecure.auth(
|
|
47
|
+
typeof options.auth === 'object' ? options.auth : undefined
|
|
48
|
+
));
|
|
163
49
|
}
|
|
164
|
-
|
|
50
|
+
|
|
165
51
|
return chain;
|
|
166
52
|
}
|
|
53
|
+
|
|
54
|
+
|
package/src/index.ts
CHANGED
|
@@ -1,33 +1,17 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// // Export the singleton instance for quick usage
|
|
6
|
-
// const hiSecure = HiSecure.getInstance();
|
|
7
|
-
|
|
8
|
-
// // Export everything
|
|
9
|
-
// export {
|
|
10
|
-
// HiSecure, // Class for advanced usage
|
|
11
|
-
// hiSecure, // Singleton instance
|
|
12
|
-
// useSecure, // Legacy function (deprecated)
|
|
13
|
-
// secureRoute // Route-level security helper
|
|
14
|
-
// };
|
|
15
|
-
|
|
16
|
-
// // Default export is the singleton instance
|
|
17
|
-
// export default hiSecure;
|
|
1
|
+
// src/index.ts - MAIN ENTRY POINT
|
|
2
|
+
import { HiSecure } from "./core/HiSecure.js";
|
|
3
|
+
import { useSecure, secureRoute } from "./core/useSecure.js";
|
|
18
4
|
|
|
5
|
+
const hiSecure = HiSecure.getInstance();
|
|
19
6
|
|
|
7
|
+
export {
|
|
8
|
+
HiSecure, // Class for advanced usage
|
|
9
|
+
hiSecure, // Singleton instance
|
|
10
|
+
useSecure, // Legacy function (deprecated)
|
|
11
|
+
secureRoute // Route-level security helper
|
|
12
|
+
};
|
|
20
13
|
|
|
14
|
+
export default hiSecure;
|
|
21
15
|
|
|
22
|
-
// src/index.ts
|
|
23
|
-
import { HiSecure } from "./core/HiSecure.js";
|
|
24
|
-
import { secureRoute } from "./core/useSecure.js"; // Only if kept
|
|
25
16
|
|
|
26
|
-
// DON'T auto-init here
|
|
27
|
-
export {
|
|
28
|
-
HiSecure, // Class
|
|
29
|
-
secureRoute // Optional sugar API
|
|
30
|
-
};
|
|
31
17
|
|
|
32
|
-
// Default export: class itself (NOT instance)
|
|
33
|
-
export default HiSecure;
|
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
// interface ValidatorAdapter {
|
|
7
|
-
// validate: (schema?: any) => any;
|
|
8
|
-
// }
|
|
1
|
+
// src/managers/ValidatorManager.ts - COMPLETE FIXED
|
|
2
|
+
import { logger } from "../logging";
|
|
3
|
+
import { ValidationError } from "../core/errors/ValidationError.js";
|
|
4
|
+
import { HiSecureConfig } from "../core/types/HiSecureConfig.js"; // ✅ FIXED IMPORT
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// private fallbackAdapter: ValidatorAdapter | null;
|
|
6
|
+
interface ValidatorAdapter {
|
|
7
|
+
validate: (schema?: any) => any;
|
|
8
|
+
}
|
|
14
9
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
10
|
+
export class ValidatorManager {
|
|
11
|
+
private config: HiSecureConfig["validation"];
|
|
12
|
+
private primaryAdapter: ValidatorAdapter;
|
|
13
|
+
private fallbackAdapter: ValidatorAdapter | null;
|
|
14
|
+
|
|
15
|
+
constructor(
|
|
16
|
+
config: HiSecureConfig["validation"],
|
|
17
|
+
primaryAdapter: ValidatorAdapter,
|
|
18
|
+
fallbackAdapter: ValidatorAdapter | null
|
|
19
|
+
) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
this.primaryAdapter = primaryAdapter;
|
|
22
|
+
this.fallbackAdapter = fallbackAdapter;
|
|
23
|
+
}
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
//
|
|
28
|
-
|
|
25
|
+
validate(schema?: any) {
|
|
26
|
+
return (req: any, res: any, next: any) => {
|
|
27
|
+
// Execute primary adapter middleware
|
|
28
|
+
const primaryMiddleware = this.primaryAdapter.validate(schema);
|
|
29
29
|
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
// Run middleware and handle errors properly
|
|
31
|
+
primaryMiddleware(req, res, (err?: any) => {
|
|
32
|
+
if (!err) {
|
|
33
|
+
return next(); // Validation passed
|
|
34
|
+
}
|
|
35
35
|
|
|
36
|
-
//
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
// If error is a ValidationError, pass it through (don't fallback!)
|
|
37
|
+
if (err instanceof ValidationError) {
|
|
38
|
+
logger.warn("⚠ Validation failed", {
|
|
39
|
+
path: req.path,
|
|
40
|
+
method: req.method,
|
|
41
|
+
error: err.message
|
|
42
|
+
});
|
|
43
|
+
return next(err);
|
|
44
|
+
}
|
|
45
45
|
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
// if (!this.fallbackAdapter) {
|
|
54
|
-
// return next(new ValidationError("Validation system error"));
|
|
55
|
-
// }
|
|
46
|
+
// Only use fallback for ADAPTER errors, not validation errors
|
|
47
|
+
logger.warn("⚠ Primary validator adapter failed", {
|
|
48
|
+
error: err?.message,
|
|
49
|
+
path: req.path,
|
|
50
|
+
method: req.method
|
|
51
|
+
});
|
|
56
52
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
//
|
|
71
|
-
|
|
53
|
+
if (!this.fallbackAdapter) {
|
|
54
|
+
return next(new ValidationError("Validation system error"));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Try fallback adapter
|
|
58
|
+
const fallbackMiddleware = this.fallbackAdapter.validate(schema);
|
|
59
|
+
fallbackMiddleware(req, res, (fallbackErr?: any) => {
|
|
60
|
+
if (fallbackErr) {
|
|
61
|
+
logger.error("❌ Fallback validator also failed", {
|
|
62
|
+
error: fallbackErr?.message
|
|
63
|
+
});
|
|
64
|
+
return next(new ValidationError("Validation system unavailable"));
|
|
65
|
+
}
|
|
66
|
+
next(); // Fallback validation passed
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
|
|
@@ -130,78 +130,78 @@
|
|
|
130
130
|
|
|
131
131
|
|
|
132
132
|
|
|
133
|
-
// src/managers/ValidatorManager.ts
|
|
134
|
-
import { logger } from "../logging";
|
|
135
|
-
import { ValidationError } from "../core/errors/ValidationError.js";
|
|
136
|
-
|
|
137
|
-
interface ValidatorAdapter {
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export class ValidatorManager {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
133
|
+
// // // src/managers/ValidatorManager.ts
|
|
134
|
+
// // import { logger } from "../logging";
|
|
135
|
+
// // import { ValidationError } from "../core/errors/ValidationError.js";
|
|
136
|
+
|
|
137
|
+
// // interface ValidatorAdapter {
|
|
138
|
+
// // validate: (schema?: any) => any;
|
|
139
|
+
// // }
|
|
140
|
+
|
|
141
|
+
// // export class ValidatorManager {
|
|
142
|
+
// // private zodAdapter: ValidatorAdapter;
|
|
143
|
+
// // private expressAdapter: ValidatorAdapter;
|
|
144
|
+
|
|
145
|
+
// // constructor(zodAdapter: ValidatorAdapter, expressAdapter: ValidatorAdapter) {
|
|
146
|
+
// // this.zodAdapter = zodAdapter;
|
|
147
|
+
// // this.expressAdapter = expressAdapter;
|
|
148
|
+
// // }
|
|
149
|
+
|
|
150
|
+
// // validate(schema?: any) {
|
|
151
|
+
// // // const isZod = schema && typeof schema.safeParse === "function";
|
|
152
|
+
// // const isZod =
|
|
153
|
+
// // schema &&
|
|
154
|
+
// // typeof schema === "object" &&
|
|
155
|
+
// // typeof schema._def === "object" &&
|
|
156
|
+
// // typeof schema.safeParse === "function";
|
|
157
|
+
|
|
158
|
+
// // const isExpressValidator = Array.isArray(schema);
|
|
159
|
+
|
|
160
|
+
// // return (req: any, res: any, next: any) => {
|
|
161
|
+
// // let middleware;
|
|
162
|
+
|
|
163
|
+
// // if (isZod) {
|
|
164
|
+
// // logger.debug("📌 Using Zod adapter");
|
|
165
|
+
// // middleware = this.zodAdapter.validate(schema);
|
|
166
|
+
// // }
|
|
167
|
+
// // else if (isExpressValidator) {
|
|
168
|
+
// // logger.debug("📌 Using express-validator adapter");
|
|
169
|
+
// // middleware = this.expressAdapter.validate(schema);
|
|
170
|
+
// // }
|
|
171
|
+
// // else {
|
|
172
|
+
// // return next(); // no schema found
|
|
173
|
+
// // }
|
|
174
|
+
|
|
175
|
+
// // // CASE 1 — express-validator returns ARRAY
|
|
176
|
+
// // if (Array.isArray(middleware)) {
|
|
177
|
+
// // let idx = 0;
|
|
178
|
+
|
|
179
|
+
// // const run = (err?: any) => {
|
|
180
|
+
// // if (err) return next(err);
|
|
181
|
+
|
|
182
|
+
// // const fn = middleware[idx++];
|
|
183
|
+
// // if (!fn) return next(); // done
|
|
184
|
+
|
|
185
|
+
// // try {
|
|
186
|
+
// // fn(req, res, run);
|
|
187
|
+
// // } catch (error: any) {
|
|
188
|
+
// // next(new ValidationError(error.message));
|
|
189
|
+
// // }
|
|
190
|
+
// // };
|
|
191
|
+
|
|
192
|
+
// // return run();
|
|
193
|
+
// // }
|
|
194
|
+
|
|
195
|
+
// // // CASE 2 — Zod returns SINGLE MIDDLEWARE
|
|
196
|
+
// // try {
|
|
197
|
+
// // middleware(req, res, (err?: any) => {
|
|
198
|
+
// // if (err) return next(err);
|
|
199
|
+
// // next();
|
|
200
|
+
// // });
|
|
201
|
+
// // } catch (err: any) {
|
|
202
|
+
// // next(new ValidationError(err.message));
|
|
203
|
+
// // }
|
|
204
|
+
// // };
|
|
205
|
+
// // }
|
|
206
|
+
// // }
|
|
207
207
|
|
|
@@ -218,21 +218,22 @@ function normalizeRateLimit(value: SecureOptions["rateLimit"]): NormalizedOption
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
function normalizeAuth(value: SecureOptions["auth"]): NormalizedOptions["auth"] {
|
|
221
|
-
// if (value === false) {
|
|
222
|
-
// return { enabled: false, required: false };
|
|
223
|
-
// }
|
|
224
221
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
222
|
+
if (value === false) {
|
|
223
|
+
return { enabled: false, required: false };
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (value === true || value === undefined) {
|
|
227
|
+
return { enabled: true, required: true };
|
|
228
|
+
}
|
|
228
229
|
|
|
229
230
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
if (value === true) {
|
|
234
|
-
|
|
235
|
-
}
|
|
231
|
+
// if (value === undefined) {
|
|
232
|
+
// return { enabled: false, required: false };
|
|
233
|
+
// }
|
|
234
|
+
// if (value === true) {
|
|
235
|
+
// return { enabled: true, required: true };
|
|
236
|
+
// }
|
|
236
237
|
|
|
237
238
|
|
|
238
239
|
const authOptions = value as AuthOptions;
|