hightjs 0.1.1

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/.idea/HightJS.iml +9 -0
  2. package/.idea/copilot.data.migration.agent.xml +6 -0
  3. package/.idea/copilot.data.migration.ask.xml +6 -0
  4. package/.idea/copilot.data.migration.ask2agent.xml +6 -0
  5. package/.idea/copilot.data.migration.edit.xml +6 -0
  6. package/.idea/inspectionProfiles/Project_Default.xml +13 -0
  7. package/.idea/libraries/test_package.xml +9 -0
  8. package/.idea/libraries/ts_commonjs_default_export.xml +9 -0
  9. package/.idea/misc.xml +7 -0
  10. package/.idea/modules.xml +8 -0
  11. package/.idea/vcs.xml +6 -0
  12. package/LICENSE +13 -0
  13. package/README.md +508 -0
  14. package/dist/adapters/express.d.ts +7 -0
  15. package/dist/adapters/express.js +63 -0
  16. package/dist/adapters/factory.d.ts +23 -0
  17. package/dist/adapters/factory.js +122 -0
  18. package/dist/adapters/fastify.d.ts +25 -0
  19. package/dist/adapters/fastify.js +61 -0
  20. package/dist/adapters/native.d.ts +8 -0
  21. package/dist/adapters/native.js +203 -0
  22. package/dist/adapters/starters/express.d.ts +0 -0
  23. package/dist/adapters/starters/express.js +1 -0
  24. package/dist/adapters/starters/factory.d.ts +0 -0
  25. package/dist/adapters/starters/factory.js +1 -0
  26. package/dist/adapters/starters/fastify.d.ts +0 -0
  27. package/dist/adapters/starters/fastify.js +1 -0
  28. package/dist/adapters/starters/index.d.ts +0 -0
  29. package/dist/adapters/starters/index.js +1 -0
  30. package/dist/adapters/starters/native.d.ts +0 -0
  31. package/dist/adapters/starters/native.js +1 -0
  32. package/dist/api/console.d.ts +92 -0
  33. package/dist/api/console.js +276 -0
  34. package/dist/api/http.d.ts +180 -0
  35. package/dist/api/http.js +467 -0
  36. package/dist/auth/client.d.ts +14 -0
  37. package/dist/auth/client.js +68 -0
  38. package/dist/auth/components.d.ts +29 -0
  39. package/dist/auth/components.js +84 -0
  40. package/dist/auth/core.d.ts +38 -0
  41. package/dist/auth/core.js +124 -0
  42. package/dist/auth/index.d.ts +7 -0
  43. package/dist/auth/index.js +27 -0
  44. package/dist/auth/jwt.d.ts +41 -0
  45. package/dist/auth/jwt.js +169 -0
  46. package/dist/auth/providers.d.ts +5 -0
  47. package/dist/auth/providers.js +14 -0
  48. package/dist/auth/react/index.d.ts +6 -0
  49. package/dist/auth/react/index.js +32 -0
  50. package/dist/auth/react.d.ts +22 -0
  51. package/dist/auth/react.js +175 -0
  52. package/dist/auth/routes.d.ts +16 -0
  53. package/dist/auth/routes.js +104 -0
  54. package/dist/auth/types.d.ts +62 -0
  55. package/dist/auth/types.js +2 -0
  56. package/dist/bin/hightjs.d.ts +2 -0
  57. package/dist/bin/hightjs.js +35 -0
  58. package/dist/builder.d.ts +32 -0
  59. package/dist/builder.js +341 -0
  60. package/dist/client/DefaultNotFound.d.ts +1 -0
  61. package/dist/client/DefaultNotFound.js +53 -0
  62. package/dist/client/ErrorBoundary.d.ts +16 -0
  63. package/dist/client/ErrorBoundary.js +181 -0
  64. package/dist/client/clientRouter.d.ts +58 -0
  65. package/dist/client/clientRouter.js +116 -0
  66. package/dist/client/entry.client.d.ts +1 -0
  67. package/dist/client/entry.client.js +271 -0
  68. package/dist/client/routerContext.d.ts +26 -0
  69. package/dist/client/routerContext.js +62 -0
  70. package/dist/client.d.ts +3 -0
  71. package/dist/client.js +8 -0
  72. package/dist/components/Link.d.ts +7 -0
  73. package/dist/components/Link.js +13 -0
  74. package/dist/eslint/index.d.ts +32 -0
  75. package/dist/eslint/index.js +15 -0
  76. package/dist/eslint/use-client-rule.d.ts +19 -0
  77. package/dist/eslint/use-client-rule.js +99 -0
  78. package/dist/eslintSetup.d.ts +0 -0
  79. package/dist/eslintSetup.js +1 -0
  80. package/dist/example/src/web/routes/index.d.ts +3 -0
  81. package/dist/example/src/web/routes/index.js +15 -0
  82. package/dist/helpers.d.ts +18 -0
  83. package/dist/helpers.js +318 -0
  84. package/dist/hotReload.d.ts +23 -0
  85. package/dist/hotReload.js +292 -0
  86. package/dist/index.d.ts +17 -0
  87. package/dist/index.js +480 -0
  88. package/dist/renderer.d.ts +14 -0
  89. package/dist/renderer.js +106 -0
  90. package/dist/router.d.ts +78 -0
  91. package/dist/router.js +359 -0
  92. package/dist/types/framework.d.ts +37 -0
  93. package/dist/types/framework.js +2 -0
  94. package/dist/types.d.ts +43 -0
  95. package/dist/types.js +2 -0
  96. package/dist/typescript/use-client-plugin.d.ts +5 -0
  97. package/dist/typescript/use-client-plugin.js +113 -0
  98. package/dist/validation.d.ts +0 -0
  99. package/dist/validation.js +1 -0
  100. package/package.json +72 -0
  101. package/src/adapters/express.ts +70 -0
  102. package/src/adapters/factory.ts +96 -0
  103. package/src/adapters/fastify.ts +88 -0
  104. package/src/adapters/native.ts +223 -0
  105. package/src/api/console.ts +285 -0
  106. package/src/api/http.ts +515 -0
  107. package/src/auth/client.ts +74 -0
  108. package/src/auth/components.tsx +109 -0
  109. package/src/auth/core.ts +143 -0
  110. package/src/auth/index.ts +9 -0
  111. package/src/auth/jwt.ts +194 -0
  112. package/src/auth/providers.ts +13 -0
  113. package/src/auth/react/index.ts +9 -0
  114. package/src/auth/react.tsx +209 -0
  115. package/src/auth/routes.ts +133 -0
  116. package/src/auth/types.ts +73 -0
  117. package/src/bin/hightjs.js +40 -0
  118. package/src/builder.js +362 -0
  119. package/src/client/DefaultNotFound.tsx +68 -0
  120. package/src/client/clientRouter.ts +137 -0
  121. package/src/client/entry.client.tsx +302 -0
  122. package/src/client.ts +8 -0
  123. package/src/components/Link.tsx +22 -0
  124. package/src/helpers.ts +316 -0
  125. package/src/hotReload.ts +289 -0
  126. package/src/index.ts +514 -0
  127. package/src/renderer.tsx +122 -0
  128. package/src/router.ts +400 -0
  129. package/src/types/framework.ts +42 -0
  130. package/src/types.ts +54 -0
  131. package/tsconfig.json +17 -0
@@ -0,0 +1,467 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HightJSResponse = exports.HightJSRequest = void 0;
4
+ // Input validation and sanitization utilities
5
+ class SecurityUtils {
6
+ static sanitizeHeader(value) {
7
+ if (Array.isArray(value)) {
8
+ return value.map(v => this.sanitizeString(v, this.MAX_HEADER_LENGTH));
9
+ }
10
+ return this.sanitizeString(value, this.MAX_HEADER_LENGTH);
11
+ }
12
+ static sanitizeString(str, maxLength) {
13
+ if (typeof str !== 'string')
14
+ return '';
15
+ // Remove null bytes and control characters except newline/tab
16
+ let clean = str.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
17
+ // Limit length
18
+ if (clean.length > maxLength) {
19
+ clean = clean.substring(0, maxLength);
20
+ }
21
+ return clean;
22
+ }
23
+ static isValidURL(url) {
24
+ if (!url || typeof url !== 'string')
25
+ return false;
26
+ if (url.length > this.MAX_URL_LENGTH)
27
+ return false;
28
+ // Basic URL validation - prevent dangerous protocols
29
+ const dangerousProtocols = ['javascript:', 'data:', 'vbscript:', 'file:'];
30
+ const lowerUrl = url.toLowerCase();
31
+ return !dangerousProtocols.some(protocol => lowerUrl.startsWith(protocol));
32
+ }
33
+ static validateContentLength(length) {
34
+ return length >= 0 && length <= this.MAX_BODY_SIZE;
35
+ }
36
+ }
37
+ SecurityUtils.MAX_HEADER_LENGTH = 8192;
38
+ SecurityUtils.MAX_COOKIE_LENGTH = 4096;
39
+ SecurityUtils.MAX_URL_LENGTH = 2048;
40
+ SecurityUtils.MAX_BODY_SIZE = 10 * 1024 * 1024; // 10MB
41
+ /**
42
+ * Abstração sobre a requisição HTTP de entrada.
43
+ * Funciona com qualquer framework web (Express, Fastify, etc.)
44
+ */
45
+ class HightJSRequest {
46
+ constructor(req) {
47
+ // Validate and sanitize request data
48
+ this._req = this.validateAndSanitizeRequest(req);
49
+ }
50
+ validateAndSanitizeRequest(req) {
51
+ // Validate URL
52
+ if (!SecurityUtils.isValidURL(req.url)) {
53
+ throw new Error('Invalid URL format');
54
+ }
55
+ // Sanitize headers
56
+ const sanitizedHeaders = {};
57
+ for (const [key, value] of Object.entries(req.headers || {})) {
58
+ const cleanKey = SecurityUtils.sanitizeString(key.toLowerCase(), 100);
59
+ if (cleanKey && value) {
60
+ sanitizedHeaders[cleanKey] = SecurityUtils.sanitizeHeader(value);
61
+ }
62
+ }
63
+ // Validate content length
64
+ const contentLength = req.headers['content-length'];
65
+ if (contentLength) {
66
+ const length = parseInt(Array.isArray(contentLength) ? contentLength[0] : contentLength, 10);
67
+ if (!SecurityUtils.validateContentLength(length)) {
68
+ throw new Error('Request too large');
69
+ }
70
+ }
71
+ // Sanitize cookies
72
+ const sanitizedCookies = {};
73
+ for (const [key, value] of Object.entries(req.cookies || {})) {
74
+ const cleanKey = SecurityUtils.sanitizeString(key, 100);
75
+ const cleanValue = SecurityUtils.sanitizeString(value, SecurityUtils.MAX_COOKIE_LENGTH);
76
+ if (cleanKey && cleanValue) {
77
+ sanitizedCookies[cleanKey] = cleanValue;
78
+ }
79
+ }
80
+ return {
81
+ ...req,
82
+ headers: sanitizedHeaders,
83
+ cookies: sanitizedCookies,
84
+ url: SecurityUtils.sanitizeString(req.url, SecurityUtils.MAX_URL_LENGTH)
85
+ };
86
+ }
87
+ /**
88
+ * Retorna o método HTTP da requisição (GET, POST, etc.)
89
+ */
90
+ get method() {
91
+ return this._req.method;
92
+ }
93
+ /**
94
+ * Retorna a URL completa da requisição
95
+ */
96
+ get url() {
97
+ return this._req.url;
98
+ }
99
+ /**
100
+ * Retorna todos os headers da requisição
101
+ */
102
+ get headers() {
103
+ return this._req.headers;
104
+ }
105
+ /**
106
+ * Retorna um header específico com validação
107
+ */
108
+ header(name) {
109
+ if (!name || typeof name !== 'string')
110
+ return undefined;
111
+ const cleanName = SecurityUtils.sanitizeString(name.toLowerCase(), 100);
112
+ return this._req.headers[cleanName];
113
+ }
114
+ /**
115
+ * Retorna todos os query parameters
116
+ */
117
+ get query() {
118
+ return this._req.query || {};
119
+ }
120
+ /**
121
+ * Retorna todos os parâmetros de rota
122
+ */
123
+ get params() {
124
+ return this._req.params || {};
125
+ }
126
+ /**
127
+ * Retorna todos os cookies
128
+ */
129
+ get cookies() {
130
+ return this._req.cookies || {};
131
+ }
132
+ /**
133
+ * Retorna um cookie específico com validação
134
+ */
135
+ cookie(name) {
136
+ if (!name || typeof name !== 'string')
137
+ return undefined;
138
+ const cleanName = SecurityUtils.sanitizeString(name, 100);
139
+ return this._req.cookies?.[cleanName];
140
+ }
141
+ /**
142
+ * Retorna o corpo (body) da requisição, já parseado como JSON com validação
143
+ */
144
+ async json() {
145
+ try {
146
+ const body = this._req.body;
147
+ // Validate JSON structure
148
+ if (typeof body === 'string') {
149
+ // Check for potential JSON bombs
150
+ if (body.length > SecurityUtils.MAX_BODY_SIZE) {
151
+ throw new Error('Request body too large');
152
+ }
153
+ return JSON.parse(body);
154
+ }
155
+ return body;
156
+ }
157
+ catch (error) {
158
+ if (error instanceof SyntaxError) {
159
+ throw new Error('Invalid JSON format');
160
+ }
161
+ throw error;
162
+ }
163
+ }
164
+ /**
165
+ * Retorna o corpo da requisição como texto
166
+ */
167
+ async text() {
168
+ if (typeof this._req.body === 'string') {
169
+ return this._req.body;
170
+ }
171
+ return JSON.stringify(this._req.body);
172
+ }
173
+ /**
174
+ * Retorna o corpo da requisição como FormData (para uploads)
175
+ */
176
+ async formData() {
177
+ return this._req.body;
178
+ }
179
+ /**
180
+ * Retorna a requisição original do framework
181
+ */
182
+ get raw() {
183
+ return this._req.raw;
184
+ }
185
+ /**
186
+ * Verifica se a requisição tem um content-type específico
187
+ */
188
+ is(type) {
189
+ const contentType = this.header('content-type');
190
+ if (!contentType)
191
+ return false;
192
+ const ct = Array.isArray(contentType) ? contentType[0] : contentType;
193
+ return ct.toLowerCase().includes(type.toLowerCase());
194
+ }
195
+ /**
196
+ * Verifica se a requisição é AJAX/XHR
197
+ */
198
+ get isAjax() {
199
+ const xhr = this.header('x-requested-with');
200
+ return xhr === 'XMLHttpRequest';
201
+ }
202
+ /**
203
+ * Retorna o IP do cliente com validação melhorada
204
+ */
205
+ get ip() {
206
+ // Check X-Forwarded-For with validation
207
+ const forwarded = this.header('x-forwarded-for');
208
+ if (forwarded) {
209
+ const ips = Array.isArray(forwarded) ? forwarded[0] : forwarded;
210
+ const firstIp = ips.split(',')[0].trim();
211
+ // Basic IP validation
212
+ if (this.isValidIP(firstIp)) {
213
+ return firstIp;
214
+ }
215
+ }
216
+ // Check X-Real-IP
217
+ const realIp = this.header('x-real-ip');
218
+ if (realIp) {
219
+ const ip = Array.isArray(realIp) ? realIp[0] : realIp;
220
+ if (this.isValidIP(ip)) {
221
+ return ip;
222
+ }
223
+ }
224
+ return 'unknown';
225
+ }
226
+ isValidIP(ip) {
227
+ if (!ip || typeof ip !== 'string')
228
+ return false;
229
+ // Basic IPv4 validation
230
+ const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
231
+ if (ipv4Regex.test(ip)) {
232
+ const parts = ip.split('.');
233
+ return parts.every(part => {
234
+ const num = parseInt(part, 10);
235
+ return num >= 0 && num <= 255;
236
+ });
237
+ }
238
+ // Basic IPv6 validation (simplified)
239
+ const ipv6Regex = /^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$/;
240
+ return ipv6Regex.test(ip);
241
+ }
242
+ /**
243
+ * Retorna o User-Agent
244
+ */
245
+ get userAgent() {
246
+ const ua = this.header('user-agent');
247
+ return Array.isArray(ua) ? ua[0] : ua;
248
+ }
249
+ }
250
+ exports.HightJSRequest = HightJSRequest;
251
+ /**
252
+ * Abstração para construir a resposta HTTP.
253
+ * Funciona com qualquer framework web (Express, Fastify, etc.)
254
+ */
255
+ class HightJSResponse {
256
+ constructor() {
257
+ this._status = 200;
258
+ this._headers = {};
259
+ this._cookies = [];
260
+ this._body = null;
261
+ this._sent = false;
262
+ }
263
+ /**
264
+ * Define o status HTTP da resposta
265
+ */
266
+ status(code) {
267
+ this._status = code;
268
+ return this;
269
+ }
270
+ /**
271
+ * Define um header da resposta
272
+ */
273
+ header(name, value) {
274
+ this._headers[name] = value;
275
+ return this;
276
+ }
277
+ /**
278
+ * Define múltiplos headers
279
+ */
280
+ headers(headers) {
281
+ Object.assign(this._headers, headers);
282
+ return this;
283
+ }
284
+ /**
285
+ * Define um cookie
286
+ */
287
+ cookie(name, value, options) {
288
+ this._cookies.push({ name, value, options });
289
+ return this;
290
+ }
291
+ /**
292
+ * Remove um cookie
293
+ */
294
+ clearCookie(name, options) {
295
+ this._cookies.push({
296
+ name,
297
+ value: '',
298
+ options: { ...options, expires: new Date(0) }
299
+ });
300
+ return this;
301
+ }
302
+ /**
303
+ * Envia resposta JSON
304
+ */
305
+ json(data) {
306
+ this._headers['Content-Type'] = 'application/json';
307
+ this._body = JSON.stringify(data);
308
+ this._sent = true;
309
+ return this;
310
+ }
311
+ /**
312
+ * Envia resposta de texto
313
+ */
314
+ text(data) {
315
+ this._headers['Content-Type'] = 'text/plain; charset=utf-8';
316
+ this._body = data;
317
+ this._sent = true;
318
+ return this;
319
+ }
320
+ /**
321
+ * Envia resposta HTML
322
+ */
323
+ html(data) {
324
+ this._headers['Content-Type'] = 'text/html; charset=utf-8';
325
+ this._body = data;
326
+ this._sent = true;
327
+ return this;
328
+ }
329
+ /**
330
+ * Envia qualquer tipo de dados
331
+ */
332
+ send(data) {
333
+ this._body = data;
334
+ this._sent = true;
335
+ return this;
336
+ }
337
+ /**
338
+ * Redireciona para uma URL
339
+ */
340
+ redirect(url, status = 302) {
341
+ this._status = status;
342
+ this._headers['Location'] = url;
343
+ this._sent = true;
344
+ return this;
345
+ }
346
+ /**
347
+ * Método interno para aplicar a resposta ao objeto de resposta do framework
348
+ */
349
+ _applyTo(res) {
350
+ // Aplica status
351
+ res.status(this._status);
352
+ // Aplica headers
353
+ Object.entries(this._headers).forEach(([name, value]) => {
354
+ res.header(name, value);
355
+ });
356
+ // Aplica cookies
357
+ this._cookies.forEach(({ name, value, options }) => {
358
+ if (options?.expires && options.expires.getTime() === 0) {
359
+ res.clearCookie(name, options);
360
+ }
361
+ else {
362
+ res.cookie(name, value, options);
363
+ }
364
+ });
365
+ // Envia o corpo se foi definido
366
+ if (this._sent && this._body !== null) {
367
+ if (this._headers['Content-Type']?.includes('application/json')) {
368
+ res.json(JSON.parse(this._body));
369
+ }
370
+ else if (this._headers['Location']) {
371
+ res.redirect(this._headers['Location']);
372
+ }
373
+ else {
374
+ res.send(this._body);
375
+ }
376
+ }
377
+ }
378
+ /**
379
+ * Método de compatibilidade com versão anterior (Express)
380
+ */
381
+ _send(res) {
382
+ // Assume que é Express se tem os métodos específicos
383
+ if (res.set && res.status && res.send) {
384
+ res.set(this._headers).status(this._status);
385
+ this._cookies.forEach(({ name, value, options }) => {
386
+ if (options?.expires && options.expires.getTime() === 0) {
387
+ res.clearCookie(name, options);
388
+ }
389
+ else {
390
+ res.cookie(name, value, options);
391
+ }
392
+ });
393
+ res.send(this._body);
394
+ }
395
+ }
396
+ // === MÉTODOS ESTÁTICOS DE CONVENIÊNCIA ===
397
+ /**
398
+ * Cria uma resposta JSON
399
+ */
400
+ static json(data, options) {
401
+ const response = new HightJSResponse();
402
+ if (options?.status)
403
+ response.status(options.status);
404
+ if (options?.headers)
405
+ response.headers(options.headers);
406
+ return response.json(data);
407
+ }
408
+ /**
409
+ * Cria uma resposta de texto
410
+ */
411
+ static text(data, options) {
412
+ const response = new HightJSResponse();
413
+ if (options?.status)
414
+ response.status(options.status);
415
+ if (options?.headers)
416
+ response.headers(options.headers);
417
+ return response.text(data);
418
+ }
419
+ /**
420
+ * Cria uma resposta HTML
421
+ */
422
+ static html(data, options) {
423
+ const response = new HightJSResponse();
424
+ if (options?.status)
425
+ response.status(options.status);
426
+ if (options?.headers)
427
+ response.headers(options.headers);
428
+ return response.html(data);
429
+ }
430
+ /**
431
+ * Cria um redirecionamento
432
+ */
433
+ static redirect(url, status = 302) {
434
+ return new HightJSResponse().redirect(url, status);
435
+ }
436
+ /**
437
+ * Cria uma resposta 404
438
+ */
439
+ static notFound(message = 'Not Found') {
440
+ return HightJSResponse.text(message, { status: 404 });
441
+ }
442
+ /**
443
+ * Cria uma resposta 500
444
+ */
445
+ static error(message = 'Internal Server Error') {
446
+ return HightJSResponse.text(message, { status: 500 });
447
+ }
448
+ /**
449
+ * Cria uma resposta 400
450
+ */
451
+ static badRequest(message = 'Bad Request') {
452
+ return HightJSResponse.text(message, { status: 400 });
453
+ }
454
+ /**
455
+ * Cria uma resposta 401
456
+ */
457
+ static unauthorized(message = 'Unauthorized') {
458
+ return HightJSResponse.text(message, { status: 401 });
459
+ }
460
+ /**
461
+ * Cria uma resposta 403
462
+ */
463
+ static forbidden(message = 'Forbidden') {
464
+ return HightJSResponse.text(message, { status: 403 });
465
+ }
466
+ }
467
+ exports.HightJSResponse = HightJSResponse;
@@ -0,0 +1,14 @@
1
+ import type { Session } from './types';
2
+ export declare function setBasePath(path: string): void;
3
+ /**
4
+ * Função para obter a sessão atual (similar ao NextAuth getSession)
5
+ */
6
+ export declare function getSession(): Promise<Session | null>;
7
+ /**
8
+ * Função para obter token CSRF
9
+ */
10
+ export declare function getCsrfToken(): Promise<string | null>;
11
+ /**
12
+ * Função para obter providers disponíveis
13
+ */
14
+ export declare function getProviders(): Promise<any[] | null>;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setBasePath = setBasePath;
4
+ exports.getSession = getSession;
5
+ exports.getCsrfToken = getCsrfToken;
6
+ exports.getProviders = getProviders;
7
+ // Configuração global do client
8
+ let basePath = '/api/auth';
9
+ function setBasePath(path) {
10
+ basePath = path;
11
+ }
12
+ /**
13
+ * Função para obter a sessão atual (similar ao NextAuth getSession)
14
+ */
15
+ async function getSession() {
16
+ try {
17
+ const response = await fetch(`${basePath}/session`, {
18
+ credentials: 'include'
19
+ });
20
+ if (!response.ok) {
21
+ return null;
22
+ }
23
+ const data = await response.json();
24
+ return data.session || null;
25
+ }
26
+ catch (error) {
27
+ console.error('[hweb-auth] Erro ao buscar sessão:', error);
28
+ return null;
29
+ }
30
+ }
31
+ /**
32
+ * Função para obter token CSRF
33
+ */
34
+ async function getCsrfToken() {
35
+ try {
36
+ const response = await fetch(`${basePath}/csrf`, {
37
+ credentials: 'include'
38
+ });
39
+ if (!response.ok) {
40
+ return null;
41
+ }
42
+ const data = await response.json();
43
+ return data.csrfToken || null;
44
+ }
45
+ catch (error) {
46
+ console.error('[hweb-auth] Erro ao buscar CSRF token:', error);
47
+ return null;
48
+ }
49
+ }
50
+ /**
51
+ * Função para obter providers disponíveis
52
+ */
53
+ async function getProviders() {
54
+ try {
55
+ const response = await fetch(`${basePath}/providers`, {
56
+ credentials: 'include'
57
+ });
58
+ if (!response.ok) {
59
+ return null;
60
+ }
61
+ const data = await response.json();
62
+ return data.providers || [];
63
+ }
64
+ catch (error) {
65
+ console.error('[hweb-auth] Erro ao buscar providers:', error);
66
+ return null;
67
+ }
68
+ }
@@ -0,0 +1,29 @@
1
+ import React, { ReactNode } from 'react';
2
+ interface ProtectedRouteProps {
3
+ children: ReactNode;
4
+ fallback?: ReactNode;
5
+ redirectTo?: string;
6
+ requireAuth?: boolean;
7
+ }
8
+ /**
9
+ * Componente para proteger rotas que requerem autenticação
10
+ */
11
+ export declare function ProtectedRoute({ children, fallback, redirectTo, requireAuth }: ProtectedRouteProps): string | number | bigint | true | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null;
12
+ interface GuardProps {
13
+ children: ReactNode;
14
+ fallback?: ReactNode;
15
+ redirectTo?: string;
16
+ }
17
+ /**
18
+ * Guard simples que só renderiza children se estiver autenticado
19
+ */
20
+ export declare function AuthGuard({ children, fallback, redirectTo }: GuardProps): string | number | bigint | true | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null;
21
+ /**
22
+ * Componente para mostrar conteúdo apenas para usuários não autenticados
23
+ */
24
+ export declare function GuestOnly({ children, fallback, redirectTo }: GuardProps): string | number | bigint | true | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element;
25
+ /**
26
+ * Hook para redirecionar baseado no status de autenticação
27
+ */
28
+ export declare function useAuthRedirect(authenticatedRedirect?: string, unauthenticatedRedirect?: string): void;
29
+ export {};
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ProtectedRoute = ProtectedRoute;
7
+ exports.AuthGuard = AuthGuard;
8
+ exports.GuestOnly = GuestOnly;
9
+ exports.useAuthRedirect = useAuthRedirect;
10
+ const jsx_runtime_1 = require("react/jsx-runtime");
11
+ const react_1 = __importDefault(require("react"));
12
+ const react_2 = require("./react");
13
+ const clientRouter_1 = require("../client/clientRouter");
14
+ /**
15
+ * Componente para proteger rotas que requerem autenticação
16
+ */
17
+ function ProtectedRoute({ children, fallback, redirectTo = '/auth/signin', requireAuth = true }) {
18
+ const { isAuthenticated, isLoading } = (0, react_2.useAuth)();
19
+ // Ainda carregando
20
+ if (isLoading) {
21
+ return fallback || (0, jsx_runtime_1.jsx)("div", { children: "Carregando..." });
22
+ }
23
+ // Requer auth mas não está autenticado
24
+ if (requireAuth && !isAuthenticated) {
25
+ if (typeof window !== 'undefined' && redirectTo) {
26
+ window.location.href = redirectTo;
27
+ return null;
28
+ }
29
+ return fallback || (0, jsx_runtime_1.jsx)("div", { children: "N\u00E3o autorizado" });
30
+ }
31
+ // Não requer auth mas está autenticado (ex: página de login)
32
+ if (!requireAuth && isAuthenticated && redirectTo) {
33
+ if (typeof window !== 'undefined') {
34
+ window.location.href = redirectTo;
35
+ return null;
36
+ }
37
+ }
38
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
39
+ }
40
+ /**
41
+ * Guard simples que só renderiza children se estiver autenticado
42
+ */
43
+ function AuthGuard({ children, fallback, redirectTo }) {
44
+ const { isAuthenticated, isLoading } = (0, react_2.useAuth)();
45
+ if (redirectTo && !isLoading && !isAuthenticated) {
46
+ clientRouter_1.router.push(redirectTo);
47
+ }
48
+ if (isLoading) {
49
+ return fallback || (0, jsx_runtime_1.jsx)("div", {});
50
+ }
51
+ if (!isAuthenticated) {
52
+ return fallback || null;
53
+ }
54
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
55
+ }
56
+ /**
57
+ * Componente para mostrar conteúdo apenas para usuários não autenticados
58
+ */
59
+ function GuestOnly({ children, fallback, redirectTo }) {
60
+ const { isAuthenticated, isLoading } = (0, react_2.useAuth)();
61
+ if (redirectTo && !isLoading && isAuthenticated) {
62
+ clientRouter_1.router.push(redirectTo);
63
+ }
64
+ if (isLoading || isAuthenticated) {
65
+ return fallback || (0, jsx_runtime_1.jsx)("div", {});
66
+ }
67
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
68
+ }
69
+ /**
70
+ * Hook para redirecionar baseado no status de autenticação
71
+ */
72
+ function useAuthRedirect(authenticatedRedirect, unauthenticatedRedirect) {
73
+ const { isAuthenticated, isLoading } = (0, react_2.useAuth)();
74
+ react_1.default.useEffect(() => {
75
+ if (isLoading)
76
+ return;
77
+ if (isAuthenticated && authenticatedRedirect) {
78
+ window.location.href = authenticatedRedirect;
79
+ }
80
+ else if (!isAuthenticated && unauthenticatedRedirect) {
81
+ window.location.href = unauthenticatedRedirect;
82
+ }
83
+ }, [isAuthenticated, isLoading, authenticatedRedirect, unauthenticatedRedirect]);
84
+ }
@@ -0,0 +1,38 @@
1
+ import { HightJSRequest, HightJSResponse } from '../api/http';
2
+ import type { AuthConfig, Session } from './types';
3
+ export declare class HWebAuth {
4
+ private config;
5
+ private sessionManager;
6
+ constructor(config: AuthConfig);
7
+ /**
8
+ * Middleware para adicionar autenticação às rotas
9
+ */
10
+ private middleware;
11
+ /**
12
+ * Autentica um usuário com credenciais
13
+ */
14
+ signIn(provider: string, credentials: Record<string, string>): Promise<{
15
+ session: Session;
16
+ token: string;
17
+ } | null>;
18
+ /**
19
+ * Faz logout do usuário
20
+ */
21
+ signOut(): HightJSResponse;
22
+ /**
23
+ * Obtém a sessão atual
24
+ */
25
+ getSession(req: HightJSRequest): Promise<Session | null>;
26
+ /**
27
+ * Verifica se o usuário está autenticado
28
+ */
29
+ isAuthenticated(req: HightJSRequest): Promise<boolean>;
30
+ /**
31
+ * Cria resposta com cookie de autenticação - Secure implementation
32
+ */
33
+ createAuthResponse(token: string, data: any): HightJSResponse;
34
+ /**
35
+ * Extrai token da requisição (cookie ou header)
36
+ */
37
+ private getTokenFromRequest;
38
+ }