create-fluxstack 1.10.1 → 1.12.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.
- package/.dockerignore +1 -2
- package/Dockerfile +8 -8
- package/LLMD/INDEX.md +64 -0
- package/LLMD/MAINTENANCE.md +197 -0
- package/LLMD/MIGRATION.md +156 -0
- package/LLMD/config/.gitkeep +1 -0
- package/LLMD/config/declarative-system.md +268 -0
- package/LLMD/config/environment-vars.md +327 -0
- package/LLMD/config/runtime-reload.md +401 -0
- package/LLMD/core/.gitkeep +1 -0
- package/LLMD/core/build-system.md +599 -0
- package/LLMD/core/framework-lifecycle.md +229 -0
- package/LLMD/core/plugin-system.md +451 -0
- package/LLMD/patterns/.gitkeep +1 -0
- package/LLMD/patterns/anti-patterns.md +297 -0
- package/LLMD/patterns/project-structure.md +264 -0
- package/LLMD/patterns/type-safety.md +440 -0
- package/LLMD/reference/.gitkeep +1 -0
- package/LLMD/reference/cli-commands.md +250 -0
- package/LLMD/reference/plugin-hooks.md +357 -0
- package/LLMD/reference/routing.md +39 -0
- package/LLMD/reference/troubleshooting.md +364 -0
- package/LLMD/resources/.gitkeep +1 -0
- package/LLMD/resources/controllers.md +465 -0
- package/LLMD/resources/live-components.md +703 -0
- package/LLMD/resources/live-rooms.md +482 -0
- package/LLMD/resources/live-upload.md +130 -0
- package/LLMD/resources/plugins-external.md +617 -0
- package/LLMD/resources/routes-eden.md +254 -0
- package/README.md +37 -17
- package/app/client/index.html +0 -1
- package/app/client/src/App.tsx +107 -150
- package/app/client/src/components/AppLayout.tsx +68 -0
- package/app/client/src/components/BackButton.tsx +13 -0
- package/app/client/src/components/DemoPage.tsx +20 -0
- package/app/client/src/components/LiveUploadWidget.tsx +204 -0
- package/app/client/src/lib/eden-api.ts +85 -60
- package/app/client/src/live/ChatDemo.tsx +107 -0
- package/app/client/src/live/CounterDemo.tsx +206 -0
- package/app/client/src/live/FormDemo.tsx +119 -0
- package/app/client/src/live/RoomChatDemo.tsx +161 -0
- package/app/client/src/live/UploadDemo.tsx +21 -0
- package/app/client/src/main.tsx +4 -1
- package/app/client/src/pages/ApiTestPage.tsx +108 -0
- package/app/client/src/pages/HomePage.tsx +76 -0
- package/app/server/app.ts +1 -4
- package/app/server/controllers/users.controller.ts +36 -44
- package/app/server/index.ts +25 -35
- package/app/server/live/LiveChat.ts +77 -0
- package/app/server/live/LiveCounter.ts +67 -0
- package/app/server/live/LiveForm.ts +63 -0
- package/app/server/live/LiveLocalCounter.ts +32 -0
- package/app/server/live/LiveRoomChat.ts +127 -0
- package/app/server/live/LiveUpload.ts +81 -0
- package/app/server/routes/index.ts +3 -1
- package/app/server/routes/room.routes.ts +117 -0
- package/app/server/routes/users.routes.ts +35 -27
- package/app/shared/types/index.ts +14 -2
- package/config/app.config.ts +2 -62
- package/config/client.config.ts +2 -95
- package/config/database.config.ts +2 -99
- package/config/fluxstack.config.ts +25 -45
- package/config/index.ts +57 -38
- package/config/monitoring.config.ts +2 -114
- package/config/plugins.config.ts +2 -80
- package/config/server.config.ts +2 -68
- package/config/services.config.ts +2 -130
- package/config/system/app.config.ts +29 -0
- package/config/system/build.config.ts +49 -0
- package/config/system/client.config.ts +68 -0
- package/config/system/database.config.ts +17 -0
- package/config/system/fluxstack.config.ts +114 -0
- package/config/{logger.config.ts → system/logger.config.ts} +3 -1
- package/config/system/monitoring.config.ts +114 -0
- package/config/system/plugins.config.ts +84 -0
- package/config/{runtime.config.ts → system/runtime.config.ts} +1 -1
- package/config/system/server.config.ts +68 -0
- package/config/system/services.config.ts +46 -0
- package/config/{system.config.ts → system/system.config.ts} +1 -1
- package/core/build/flux-plugins-generator.ts +325 -325
- package/core/build/index.ts +39 -27
- package/core/build/live-components-generator.ts +3 -3
- package/core/build/optimizer.ts +235 -235
- package/core/cli/command-registry.ts +6 -4
- package/core/cli/commands/build.ts +79 -0
- package/core/cli/commands/create.ts +54 -0
- package/core/cli/commands/dev.ts +101 -0
- package/core/cli/commands/help.ts +34 -0
- package/core/cli/commands/index.ts +34 -0
- package/core/cli/commands/make-plugin.ts +90 -0
- package/core/cli/commands/plugin-add.ts +197 -0
- package/core/cli/commands/plugin-deps.ts +2 -2
- package/core/cli/commands/plugin-list.ts +208 -0
- package/core/cli/commands/plugin-remove.ts +170 -0
- package/core/cli/generators/component.ts +769 -769
- package/core/cli/generators/controller.ts +1 -1
- package/core/cli/generators/index.ts +146 -146
- package/core/cli/generators/interactive.ts +227 -227
- package/core/cli/generators/plugin.ts +2 -2
- package/core/cli/generators/prompts.ts +82 -82
- package/core/cli/generators/route.ts +6 -6
- package/core/cli/generators/service.ts +2 -2
- package/core/cli/generators/template-engine.ts +4 -3
- package/core/cli/generators/types.ts +2 -2
- package/core/cli/generators/utils.ts +191 -191
- package/core/cli/index.ts +115 -686
- package/core/cli/plugin-discovery.ts +2 -2
- package/core/client/LiveComponentsProvider.tsx +60 -8
- package/core/client/api/eden.ts +183 -0
- package/core/client/api/index.ts +11 -0
- package/core/client/components/Live.tsx +104 -0
- package/core/client/fluxstack.ts +1 -9
- package/core/client/hooks/AdaptiveChunkSizer.ts +215 -215
- package/core/client/hooks/state-validator.ts +1 -1
- package/core/client/hooks/useAuth.ts +48 -48
- package/core/client/hooks/useChunkedUpload.ts +85 -35
- package/core/client/hooks/useLiveChunkedUpload.ts +87 -0
- package/core/client/hooks/useLiveComponent.ts +800 -0
- package/core/client/hooks/useLiveUpload.ts +71 -0
- package/core/client/hooks/useRoom.ts +409 -0
- package/core/client/hooks/useRoomProxy.ts +382 -0
- package/core/client/index.ts +17 -68
- package/core/client/standalone-entry.ts +8 -0
- package/core/client/standalone.ts +74 -53
- package/core/client/state/createStore.ts +192 -192
- package/core/client/state/index.ts +14 -14
- package/core/config/index.ts +70 -291
- package/core/config/schema.ts +42 -723
- package/core/framework/client.ts +131 -131
- package/core/framework/index.ts +7 -7
- package/core/framework/server.ts +47 -40
- package/core/framework/types.ts +2 -2
- package/core/index.ts +23 -4
- package/core/live/ComponentRegistry.ts +3 -3
- package/core/live/types.ts +77 -0
- package/core/plugins/built-in/index.ts +134 -134
- package/core/plugins/built-in/live-components/commands/create-live-component.ts +242 -1066
- package/core/plugins/built-in/live-components/index.ts +1 -1
- package/core/plugins/built-in/monitoring/index.ts +111 -47
- package/core/plugins/built-in/static/index.ts +1 -1
- package/core/plugins/built-in/swagger/index.ts +68 -265
- package/core/plugins/built-in/vite/index.ts +85 -185
- package/core/plugins/built-in/vite/vite-dev.ts +10 -16
- package/core/plugins/config.ts +9 -7
- package/core/plugins/dependency-manager.ts +31 -1
- package/core/plugins/discovery.ts +19 -7
- package/core/plugins/executor.ts +2 -2
- package/core/plugins/index.ts +203 -203
- package/core/plugins/manager.ts +27 -39
- package/core/plugins/module-resolver.ts +19 -8
- package/core/plugins/registry.ts +255 -19
- package/core/plugins/types.ts +20 -53
- package/core/server/framework.ts +66 -43
- package/core/server/index.ts +15 -15
- package/core/server/live/ComponentRegistry.ts +78 -71
- package/core/server/live/FileUploadManager.ts +23 -10
- package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
- package/core/server/live/LiveRoomManager.ts +261 -0
- package/core/server/live/RoomEventBus.ts +234 -0
- package/core/server/live/RoomStateManager.ts +172 -0
- package/core/server/live/StateSignature.ts +643 -643
- package/core/server/live/WebSocketConnectionManager.ts +30 -19
- package/core/server/live/auto-generated-components.ts +21 -9
- package/core/server/live/index.ts +14 -0
- package/core/server/live/websocket-plugin.ts +214 -67
- package/core/server/middleware/elysia-helpers.ts +7 -2
- package/core/server/middleware/errorHandling.ts +1 -1
- package/core/server/middleware/index.ts +31 -31
- package/core/server/plugins/database.ts +180 -180
- package/core/server/plugins/static-files-plugin.ts +69 -69
- package/core/server/plugins/swagger.ts +1 -1
- package/core/server/rooms/RoomBroadcaster.ts +357 -0
- package/core/server/rooms/RoomSystem.ts +463 -0
- package/core/server/rooms/index.ts +13 -0
- package/core/server/services/BaseService.ts +1 -1
- package/core/server/services/ServiceContainer.ts +1 -1
- package/core/server/services/index.ts +8 -8
- package/core/templates/create-project.ts +12 -12
- package/core/testing/index.ts +9 -9
- package/core/testing/setup.ts +73 -73
- package/core/types/api.ts +168 -168
- package/core/types/build.ts +219 -219
- package/core/types/config.ts +56 -26
- package/core/types/index.ts +4 -4
- package/core/types/plugin.ts +107 -107
- package/core/types/types.ts +353 -14
- package/core/utils/build-logger.ts +324 -324
- package/core/utils/config-schema.ts +480 -480
- package/core/utils/env.ts +2 -8
- package/core/utils/errors/codes.ts +114 -114
- package/core/utils/errors/handlers.ts +36 -1
- package/core/utils/errors/index.ts +49 -5
- package/core/utils/errors/middleware.ts +113 -113
- package/core/utils/helpers.ts +6 -16
- package/core/utils/index.ts +17 -17
- package/core/utils/logger/colors.ts +114 -114
- package/core/utils/logger/config.ts +13 -9
- package/core/utils/logger/formatter.ts +82 -82
- package/core/utils/logger/group-logger.ts +101 -101
- package/core/utils/logger/index.ts +6 -1
- package/core/utils/logger/stack-trace.ts +3 -1
- package/core/utils/logger/startup-banner.ts +82 -82
- package/core/utils/logger/winston-logger.ts +152 -152
- package/core/utils/monitoring/index.ts +211 -211
- package/core/utils/sync-version.ts +66 -66
- package/core/utils/version.ts +1 -1
- package/create-fluxstack.ts +8 -7
- package/package.json +12 -13
- package/plugins/crypto-auth/cli/make-protected-route.command.ts +1 -1
- package/plugins/crypto-auth/client/CryptoAuthClient.ts +302 -302
- package/plugins/crypto-auth/client/components/index.ts +11 -11
- package/plugins/crypto-auth/client/index.ts +11 -11
- package/plugins/crypto-auth/config/index.ts +1 -1
- package/plugins/crypto-auth/index.ts +4 -4
- package/plugins/crypto-auth/package.json +65 -65
- package/plugins/crypto-auth/server/AuthMiddleware.ts +1 -1
- package/plugins/crypto-auth/server/CryptoAuthService.ts +185 -185
- package/plugins/crypto-auth/server/index.ts +21 -21
- package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +3 -3
- package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +1 -1
- package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +2 -2
- package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +2 -2
- package/plugins/crypto-auth/server/middlewares/helpers.ts +1 -1
- package/plugins/crypto-auth/server/middlewares/index.ts +22 -22
- package/tsconfig.api-strict.json +16 -0
- package/tsconfig.json +48 -52
- package/{app/client/tsconfig.node.json → tsconfig.node.json} +25 -25
- package/types/global.d.ts +29 -29
- package/types/vitest.d.ts +8 -8
- package/vite.config.ts +38 -62
- package/vitest.config.live.ts +10 -9
- package/vitest.config.ts +29 -17
- package/app/client/README.md +0 -69
- package/app/client/SIMPLIFICATION.md +0 -140
- package/app/client/frontend-only.ts +0 -12
- package/app/client/src/live/FileUploadExample.tsx +0 -359
- package/app/client/src/live/MinimalLiveClock.tsx +0 -47
- package/app/client/src/live/QuickUploadTest.tsx +0 -193
- package/app/client/tsconfig.app.json +0 -45
- package/app/client/tsconfig.json +0 -7
- package/app/client/zustand-setup.md +0 -65
- package/app/server/backend-only.ts +0 -18
- package/app/server/live/LiveClockComponent.ts +0 -215
- package/app/server/live/LiveFileUploadComponent.ts +0 -77
- package/app/server/routes/env-test.ts +0 -110
- package/core/client/hooks/index.ts +0 -7
- package/core/client/hooks/useHybridLiveComponent.ts +0 -685
- package/core/client/hooks/useTypedLiveComponent.ts +0 -133
- package/core/client/hooks/useWebSocket.ts +0 -361
- package/core/config/env.ts +0 -546
- package/core/config/loader.ts +0 -522
- package/core/config/runtime-config.ts +0 -327
- package/core/config/validator.ts +0 -540
- package/core/server/backend-entry.ts +0 -51
- package/core/server/standalone.ts +0 -106
- package/core/utils/regenerate-files.ts +0 -69
- package/fluxstack.config.ts +0 -354
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Sistema de autenticação baseado em criptografia Ed25519
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { FluxStack, PluginContext, RequestContext, ResponseContext } from "
|
|
6
|
+
import type { FluxStack, PluginContext, RequestContext, ResponseContext } from "@core/plugins/types"
|
|
7
7
|
|
|
8
8
|
type Plugin = FluxStack.Plugin
|
|
9
9
|
import { Elysia, t } from "elysia"
|
|
@@ -74,8 +74,8 @@ export const cryptoAuthPlugin: Plugin = {
|
|
|
74
74
|
|
|
75
75
|
// Inicializar serviço de autenticação (SEM SESSÕES)
|
|
76
76
|
const authService = new CryptoAuthService({
|
|
77
|
-
maxTimeDrift: cryptoAuthConfig.maxTimeDrift,
|
|
78
|
-
adminKeys: cryptoAuthConfig.adminKeys,
|
|
77
|
+
maxTimeDrift: cryptoAuthConfig.maxTimeDrift ?? 300000,
|
|
78
|
+
adminKeys: cryptoAuthConfig.adminKeys ?? [],
|
|
79
79
|
logger: context.logger
|
|
80
80
|
})
|
|
81
81
|
|
|
@@ -95,7 +95,7 @@ export const cryptoAuthPlugin: Plugin = {
|
|
|
95
95
|
(global as any).__fluxstackPlugins.push({
|
|
96
96
|
name: 'Crypto Auth',
|
|
97
97
|
status: 'Active',
|
|
98
|
-
details: `${cryptoAuthConfig.adminKeys.length} admin keys`
|
|
98
|
+
details: `${(cryptoAuthConfig.adminKeys ?? []).length} admin keys`
|
|
99
99
|
})
|
|
100
100
|
},
|
|
101
101
|
|
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@fluxstack/crypto-auth-plugin",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"description": "Plugin de autenticação criptográfica Ed25519 para FluxStack",
|
|
5
|
-
"main": "index.ts",
|
|
6
|
-
"types": "index.ts",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": {
|
|
9
|
-
"import": "./index.ts",
|
|
10
|
-
"types": "./index.ts"
|
|
11
|
-
},
|
|
12
|
-
"./client": {
|
|
13
|
-
"import": "./client/index.ts",
|
|
14
|
-
"types": "./client/index.ts"
|
|
15
|
-
},
|
|
16
|
-
"./server": {
|
|
17
|
-
"import": "./server/index.ts",
|
|
18
|
-
"types": "./server/index.ts"
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
"keywords": [
|
|
22
|
-
"fluxstack",
|
|
23
|
-
"plugin",
|
|
24
|
-
"authentication",
|
|
25
|
-
"ed25519",
|
|
26
|
-
"cryptography",
|
|
27
|
-
"security",
|
|
28
|
-
"react",
|
|
29
|
-
"typescript"
|
|
30
|
-
],
|
|
31
|
-
"author": "FluxStack Team",
|
|
32
|
-
"license": "MIT",
|
|
33
|
-
"peerDependencies": {
|
|
34
|
-
"react": ">=16.8.0"
|
|
35
|
-
},
|
|
36
|
-
"peerDependenciesMeta": {
|
|
37
|
-
"react": {
|
|
38
|
-
"optional": true
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
"dependencies": {
|
|
42
|
-
"@noble/curves": "1.2.0",
|
|
43
|
-
"@noble/hashes": "1.3.2"
|
|
44
|
-
},
|
|
45
|
-
"devDependencies": {
|
|
46
|
-
"@types/react": "^18.0.0",
|
|
47
|
-
"typescript": "^5.0.0"
|
|
48
|
-
},
|
|
49
|
-
"fluxstack": {
|
|
50
|
-
"plugin": true,
|
|
51
|
-
"version": "^1.0.0",
|
|
52
|
-
"hooks": [
|
|
53
|
-
"setup",
|
|
54
|
-
"onServerStart",
|
|
55
|
-
"onRequest",
|
|
56
|
-
"onResponse"
|
|
57
|
-
],
|
|
58
|
-
"category": "auth",
|
|
59
|
-
"tags": [
|
|
60
|
-
"authentication",
|
|
61
|
-
"ed25519",
|
|
62
|
-
"cryptography",
|
|
63
|
-
"security"
|
|
64
|
-
]
|
|
65
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@fluxstack/crypto-auth-plugin",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Plugin de autenticação criptográfica Ed25519 para FluxStack",
|
|
5
|
+
"main": "index.ts",
|
|
6
|
+
"types": "index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./index.ts",
|
|
10
|
+
"types": "./index.ts"
|
|
11
|
+
},
|
|
12
|
+
"./client": {
|
|
13
|
+
"import": "./client/index.ts",
|
|
14
|
+
"types": "./client/index.ts"
|
|
15
|
+
},
|
|
16
|
+
"./server": {
|
|
17
|
+
"import": "./server/index.ts",
|
|
18
|
+
"types": "./server/index.ts"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"fluxstack",
|
|
23
|
+
"plugin",
|
|
24
|
+
"authentication",
|
|
25
|
+
"ed25519",
|
|
26
|
+
"cryptography",
|
|
27
|
+
"security",
|
|
28
|
+
"react",
|
|
29
|
+
"typescript"
|
|
30
|
+
],
|
|
31
|
+
"author": "FluxStack Team",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"react": ">=16.8.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"react": {
|
|
38
|
+
"optional": true
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@noble/curves": "1.2.0",
|
|
43
|
+
"@noble/hashes": "1.3.2"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/react": "^18.0.0",
|
|
47
|
+
"typescript": "^5.0.0"
|
|
48
|
+
},
|
|
49
|
+
"fluxstack": {
|
|
50
|
+
"plugin": true,
|
|
51
|
+
"version": "^1.0.0",
|
|
52
|
+
"hooks": [
|
|
53
|
+
"setup",
|
|
54
|
+
"onServerStart",
|
|
55
|
+
"onRequest",
|
|
56
|
+
"onResponse"
|
|
57
|
+
],
|
|
58
|
+
"category": "auth",
|
|
59
|
+
"tags": [
|
|
60
|
+
"authentication",
|
|
61
|
+
"ed25519",
|
|
62
|
+
"cryptography",
|
|
63
|
+
"security"
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
66
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Apenas valida autenticação - routing é feito pelos middlewares Elysia
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { RequestContext } from '
|
|
6
|
+
import type { RequestContext } from '@core/plugins/types'
|
|
7
7
|
import type { CryptoAuthService } from './CryptoAuthService'
|
|
8
8
|
|
|
9
9
|
export interface Logger {
|
|
@@ -1,186 +1,186 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Serviço de Autenticação Criptográfica
|
|
3
|
-
* Implementa autenticação baseada em Ed25519 - SEM SESSÕES
|
|
4
|
-
* Cada requisição é validada pela assinatura da chave pública
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { ed25519 } from '@noble/curves/ed25519'
|
|
8
|
-
import { sha256 } from '@noble/hashes/sha256'
|
|
9
|
-
import { hexToBytes } from '@noble/hashes/utils'
|
|
10
|
-
|
|
11
|
-
export interface Logger {
|
|
12
|
-
debug(message: string, meta?: any): void
|
|
13
|
-
info(message: string, meta?: any): void
|
|
14
|
-
warn(message: string, meta?: any): void
|
|
15
|
-
error(message: string, meta?: any): void
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface AuthResult {
|
|
19
|
-
success: boolean
|
|
20
|
-
error?: string
|
|
21
|
-
user?: {
|
|
22
|
-
publicKey: string
|
|
23
|
-
isAdmin: boolean
|
|
24
|
-
permissions: string[]
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface CryptoAuthConfig {
|
|
29
|
-
maxTimeDrift: number
|
|
30
|
-
adminKeys: string[]
|
|
31
|
-
logger?: Logger
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export class CryptoAuthService {
|
|
35
|
-
private config: CryptoAuthConfig
|
|
36
|
-
private logger?: Logger
|
|
37
|
-
private usedNonces: Map<string, number> = new Map() // Para prevenir replay attacks
|
|
38
|
-
|
|
39
|
-
constructor(config: CryptoAuthConfig) {
|
|
40
|
-
this.config = config
|
|
41
|
-
this.logger = config.logger
|
|
42
|
-
|
|
43
|
-
// Limpar nonces antigos a cada 5 minutos
|
|
44
|
-
setInterval(() => {
|
|
45
|
-
this.cleanupOldNonces()
|
|
46
|
-
}, 5 * 60 * 1000)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Validar assinatura de requisição
|
|
51
|
-
* PRINCIPAL: Valida se assinatura é válida para a chave pública fornecida
|
|
52
|
-
*/
|
|
53
|
-
async validateRequest(data: {
|
|
54
|
-
publicKey: string
|
|
55
|
-
timestamp: number
|
|
56
|
-
nonce: string
|
|
57
|
-
signature: string
|
|
58
|
-
message?: string
|
|
59
|
-
}): Promise<AuthResult> {
|
|
60
|
-
try {
|
|
61
|
-
const { publicKey, timestamp, nonce, signature, message = "" } = data
|
|
62
|
-
|
|
63
|
-
// Validar chave pública
|
|
64
|
-
if (!this.isValidPublicKey(publicKey)) {
|
|
65
|
-
return {
|
|
66
|
-
success: false,
|
|
67
|
-
error: "Chave pública inválida"
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Verificar drift de tempo (previne replay de requisições antigas)
|
|
72
|
-
const now = Date.now()
|
|
73
|
-
const timeDrift = Math.abs(now - timestamp)
|
|
74
|
-
if (timeDrift > this.config.maxTimeDrift) {
|
|
75
|
-
return {
|
|
76
|
-
success: false,
|
|
77
|
-
error: "Timestamp inválido ou expirado"
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Verificar nonce (previne replay attacks)
|
|
82
|
-
const nonceKey = `${publicKey}:${nonce}`
|
|
83
|
-
if (this.usedNonces.has(nonceKey)) {
|
|
84
|
-
return {
|
|
85
|
-
success: false,
|
|
86
|
-
error: "Nonce já utilizado (possível replay attack)"
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Construir mensagem para verificação
|
|
91
|
-
const messageToVerify = `${publicKey}:${timestamp}:${nonce}:${message}`
|
|
92
|
-
const messageHash = sha256(new TextEncoder().encode(messageToVerify))
|
|
93
|
-
|
|
94
|
-
// Verificar assinatura usando chave pública
|
|
95
|
-
const publicKeyBytes = hexToBytes(publicKey)
|
|
96
|
-
const signatureBytes = hexToBytes(signature)
|
|
97
|
-
|
|
98
|
-
const isValidSignature = ed25519.verify(signatureBytes, messageHash, publicKeyBytes)
|
|
99
|
-
|
|
100
|
-
if (!isValidSignature) {
|
|
101
|
-
this.logger?.warn("Assinatura inválida", {
|
|
102
|
-
publicKey: publicKey.substring(0, 8) + "..."
|
|
103
|
-
})
|
|
104
|
-
return {
|
|
105
|
-
success: false,
|
|
106
|
-
error: "Assinatura inválida"
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Marcar nonce como usado
|
|
111
|
-
this.usedNonces.set(nonceKey, timestamp)
|
|
112
|
-
|
|
113
|
-
// Verificar se é admin
|
|
114
|
-
const isAdmin = this.config.adminKeys.includes(publicKey)
|
|
115
|
-
const permissions = isAdmin ? ['admin', 'read', 'write', 'delete'] : ['read']
|
|
116
|
-
|
|
117
|
-
this.logger?.debug("Requisição autenticada", {
|
|
118
|
-
publicKey: publicKey.substring(0, 8) + "...",
|
|
119
|
-
isAdmin,
|
|
120
|
-
permissions
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
return {
|
|
124
|
-
success: true,
|
|
125
|
-
user: {
|
|
126
|
-
publicKey,
|
|
127
|
-
isAdmin,
|
|
128
|
-
permissions
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
} catch (error) {
|
|
132
|
-
this.logger?.error("Erro ao validar requisição", { error })
|
|
133
|
-
return {
|
|
134
|
-
success: false,
|
|
135
|
-
error: "Erro interno ao validar requisição"
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Verificar se uma chave pública é válida
|
|
142
|
-
*/
|
|
143
|
-
private isValidPublicKey(publicKey: string): boolean {
|
|
144
|
-
try {
|
|
145
|
-
if (publicKey.length !== 64) {
|
|
146
|
-
return false
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const bytes = hexToBytes(publicKey)
|
|
150
|
-
return bytes.length === 32
|
|
151
|
-
} catch {
|
|
152
|
-
return false
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Limpar nonces antigos (previne crescimento infinito da memória)
|
|
158
|
-
*/
|
|
159
|
-
private cleanupOldNonces(): void {
|
|
160
|
-
const now = Date.now()
|
|
161
|
-
const maxAge = this.config.maxTimeDrift * 2 // Dobro do tempo máximo permitido
|
|
162
|
-
let cleanedCount = 0
|
|
163
|
-
|
|
164
|
-
for (const [nonceKey, timestamp] of this.usedNonces.entries()) {
|
|
165
|
-
if (now - timestamp > maxAge) {
|
|
166
|
-
this.usedNonces.delete(nonceKey)
|
|
167
|
-
cleanedCount++
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (cleanedCount > 0) {
|
|
172
|
-
this.logger?.debug(`Limpeza de nonces: ${cleanedCount} nonces antigos removidos`)
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Obter estatísticas do serviço
|
|
178
|
-
*/
|
|
179
|
-
getStats() {
|
|
180
|
-
return {
|
|
181
|
-
usedNoncesCount: this.usedNonces.size,
|
|
182
|
-
adminKeys: this.config.adminKeys.length,
|
|
183
|
-
maxTimeDrift: this.config.maxTimeDrift
|
|
184
|
-
}
|
|
185
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Serviço de Autenticação Criptográfica
|
|
3
|
+
* Implementa autenticação baseada em Ed25519 - SEM SESSÕES
|
|
4
|
+
* Cada requisição é validada pela assinatura da chave pública
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ed25519 } from '@noble/curves/ed25519'
|
|
8
|
+
import { sha256 } from '@noble/hashes/sha256'
|
|
9
|
+
import { hexToBytes } from '@noble/hashes/utils'
|
|
10
|
+
|
|
11
|
+
export interface Logger {
|
|
12
|
+
debug(message: string, meta?: any): void
|
|
13
|
+
info(message: string, meta?: any): void
|
|
14
|
+
warn(message: string, meta?: any): void
|
|
15
|
+
error(message: string, meta?: any): void
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AuthResult {
|
|
19
|
+
success: boolean
|
|
20
|
+
error?: string
|
|
21
|
+
user?: {
|
|
22
|
+
publicKey: string
|
|
23
|
+
isAdmin: boolean
|
|
24
|
+
permissions: string[]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface CryptoAuthConfig {
|
|
29
|
+
maxTimeDrift: number
|
|
30
|
+
adminKeys: string[]
|
|
31
|
+
logger?: Logger
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class CryptoAuthService {
|
|
35
|
+
private config: CryptoAuthConfig
|
|
36
|
+
private logger?: Logger
|
|
37
|
+
private usedNonces: Map<string, number> = new Map() // Para prevenir replay attacks
|
|
38
|
+
|
|
39
|
+
constructor(config: CryptoAuthConfig) {
|
|
40
|
+
this.config = config
|
|
41
|
+
this.logger = config.logger
|
|
42
|
+
|
|
43
|
+
// Limpar nonces antigos a cada 5 minutos
|
|
44
|
+
setInterval(() => {
|
|
45
|
+
this.cleanupOldNonces()
|
|
46
|
+
}, 5 * 60 * 1000)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Validar assinatura de requisição
|
|
51
|
+
* PRINCIPAL: Valida se assinatura é válida para a chave pública fornecida
|
|
52
|
+
*/
|
|
53
|
+
async validateRequest(data: {
|
|
54
|
+
publicKey: string
|
|
55
|
+
timestamp: number
|
|
56
|
+
nonce: string
|
|
57
|
+
signature: string
|
|
58
|
+
message?: string
|
|
59
|
+
}): Promise<AuthResult> {
|
|
60
|
+
try {
|
|
61
|
+
const { publicKey, timestamp, nonce, signature, message = "" } = data
|
|
62
|
+
|
|
63
|
+
// Validar chave pública
|
|
64
|
+
if (!this.isValidPublicKey(publicKey)) {
|
|
65
|
+
return {
|
|
66
|
+
success: false,
|
|
67
|
+
error: "Chave pública inválida"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Verificar drift de tempo (previne replay de requisições antigas)
|
|
72
|
+
const now = Date.now()
|
|
73
|
+
const timeDrift = Math.abs(now - timestamp)
|
|
74
|
+
if (timeDrift > this.config.maxTimeDrift) {
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
error: "Timestamp inválido ou expirado"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Verificar nonce (previne replay attacks)
|
|
82
|
+
const nonceKey = `${publicKey}:${nonce}`
|
|
83
|
+
if (this.usedNonces.has(nonceKey)) {
|
|
84
|
+
return {
|
|
85
|
+
success: false,
|
|
86
|
+
error: "Nonce já utilizado (possível replay attack)"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Construir mensagem para verificação
|
|
91
|
+
const messageToVerify = `${publicKey}:${timestamp}:${nonce}:${message}`
|
|
92
|
+
const messageHash = sha256(new TextEncoder().encode(messageToVerify))
|
|
93
|
+
|
|
94
|
+
// Verificar assinatura usando chave pública
|
|
95
|
+
const publicKeyBytes = hexToBytes(publicKey)
|
|
96
|
+
const signatureBytes = hexToBytes(signature)
|
|
97
|
+
|
|
98
|
+
const isValidSignature = ed25519.verify(signatureBytes, messageHash, publicKeyBytes)
|
|
99
|
+
|
|
100
|
+
if (!isValidSignature) {
|
|
101
|
+
this.logger?.warn("Assinatura inválida", {
|
|
102
|
+
publicKey: publicKey.substring(0, 8) + "..."
|
|
103
|
+
})
|
|
104
|
+
return {
|
|
105
|
+
success: false,
|
|
106
|
+
error: "Assinatura inválida"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Marcar nonce como usado
|
|
111
|
+
this.usedNonces.set(nonceKey, timestamp)
|
|
112
|
+
|
|
113
|
+
// Verificar se é admin
|
|
114
|
+
const isAdmin = this.config.adminKeys.includes(publicKey)
|
|
115
|
+
const permissions = isAdmin ? ['admin', 'read', 'write', 'delete'] : ['read']
|
|
116
|
+
|
|
117
|
+
this.logger?.debug("Requisição autenticada", {
|
|
118
|
+
publicKey: publicKey.substring(0, 8) + "...",
|
|
119
|
+
isAdmin,
|
|
120
|
+
permissions
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
success: true,
|
|
125
|
+
user: {
|
|
126
|
+
publicKey,
|
|
127
|
+
isAdmin,
|
|
128
|
+
permissions
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
} catch (error) {
|
|
132
|
+
this.logger?.error("Erro ao validar requisição", { error })
|
|
133
|
+
return {
|
|
134
|
+
success: false,
|
|
135
|
+
error: "Erro interno ao validar requisição"
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Verificar se uma chave pública é válida
|
|
142
|
+
*/
|
|
143
|
+
private isValidPublicKey(publicKey: string): boolean {
|
|
144
|
+
try {
|
|
145
|
+
if (publicKey.length !== 64) {
|
|
146
|
+
return false
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const bytes = hexToBytes(publicKey)
|
|
150
|
+
return bytes.length === 32
|
|
151
|
+
} catch {
|
|
152
|
+
return false
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Limpar nonces antigos (previne crescimento infinito da memória)
|
|
158
|
+
*/
|
|
159
|
+
private cleanupOldNonces(): void {
|
|
160
|
+
const now = Date.now()
|
|
161
|
+
const maxAge = this.config.maxTimeDrift * 2 // Dobro do tempo máximo permitido
|
|
162
|
+
let cleanedCount = 0
|
|
163
|
+
|
|
164
|
+
for (const [nonceKey, timestamp] of this.usedNonces.entries()) {
|
|
165
|
+
if (now - timestamp > maxAge) {
|
|
166
|
+
this.usedNonces.delete(nonceKey)
|
|
167
|
+
cleanedCount++
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (cleanedCount > 0) {
|
|
172
|
+
this.logger?.debug(`Limpeza de nonces: ${cleanedCount} nonces antigos removidos`)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Obter estatísticas do serviço
|
|
178
|
+
*/
|
|
179
|
+
getStats() {
|
|
180
|
+
return {
|
|
181
|
+
usedNoncesCount: this.usedNonces.size,
|
|
182
|
+
adminKeys: this.config.adminKeys.length,
|
|
183
|
+
maxTimeDrift: this.config.maxTimeDrift
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
186
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Exportações do servidor de autenticação
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export { CryptoAuthService } from './CryptoAuthService'
|
|
6
|
-
export type { AuthResult, CryptoAuthConfig } from './CryptoAuthService'
|
|
7
|
-
|
|
8
|
-
export { AuthMiddleware } from './AuthMiddleware'
|
|
9
|
-
export type { AuthMiddlewareConfig, AuthMiddlewareResult } from './AuthMiddleware'
|
|
10
|
-
|
|
11
|
-
// Middlewares Elysia
|
|
12
|
-
export {
|
|
13
|
-
cryptoAuthRequired,
|
|
14
|
-
cryptoAuthAdmin,
|
|
15
|
-
cryptoAuthPermissions,
|
|
16
|
-
cryptoAuthOptional,
|
|
17
|
-
getCryptoAuthUser,
|
|
18
|
-
isCryptoAuthAuthenticated,
|
|
19
|
-
isCryptoAuthAdmin,
|
|
20
|
-
hasCryptoAuthPermission
|
|
21
|
-
} from './middlewares'
|
|
1
|
+
/**
|
|
2
|
+
* Exportações do servidor de autenticação
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export { CryptoAuthService } from './CryptoAuthService'
|
|
6
|
+
export type { AuthResult, CryptoAuthConfig } from './CryptoAuthService'
|
|
7
|
+
|
|
8
|
+
export { AuthMiddleware } from './AuthMiddleware'
|
|
9
|
+
export type { AuthMiddlewareConfig, AuthMiddlewareResult } from './AuthMiddleware'
|
|
10
|
+
|
|
11
|
+
// Middlewares Elysia
|
|
12
|
+
export {
|
|
13
|
+
cryptoAuthRequired,
|
|
14
|
+
cryptoAuthAdmin,
|
|
15
|
+
cryptoAuthPermissions,
|
|
16
|
+
cryptoAuthOptional,
|
|
17
|
+
getCryptoAuthUser,
|
|
18
|
+
isCryptoAuthAuthenticated,
|
|
19
|
+
isCryptoAuthAdmin,
|
|
20
|
+
hasCryptoAuthPermission
|
|
21
|
+
} from './middlewares'
|
|
22
22
|
export type { CryptoAuthUser, CryptoAuthMiddlewareOptions } from './middlewares'
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { Elysia } from 'elysia'
|
|
7
|
-
import { createGuard } from '
|
|
8
|
-
import type { Logger } from '
|
|
7
|
+
import { createGuard } from '@core/server/middleware/elysia-helpers'
|
|
8
|
+
import type { Logger } from '@core/utils/logger'
|
|
9
9
|
import { validateAuthSync, type CryptoAuthUser } from './helpers'
|
|
10
10
|
|
|
11
11
|
export interface CryptoAuthMiddlewareOptions {
|
|
@@ -28,7 +28,7 @@ export const cryptoAuthAdmin = (options: CryptoAuthMiddlewareOptions = {}) => {
|
|
|
28
28
|
name: 'crypto-auth-admin-check',
|
|
29
29
|
check: ({ request }) => {
|
|
30
30
|
const user = (request as any).user as CryptoAuthUser | undefined
|
|
31
|
-
return user && user.isAdmin
|
|
31
|
+
return !!(user && user.isAdmin)
|
|
32
32
|
},
|
|
33
33
|
onFail: (set, { request }) => {
|
|
34
34
|
const user = (request as any).user as CryptoAuthUser | undefined
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { Elysia } from 'elysia'
|
|
7
|
-
import { createGuard } from '
|
|
8
|
-
import type { Logger } from '
|
|
7
|
+
import { createGuard } from '@core/server/middleware/elysia-helpers'
|
|
8
|
+
import type { Logger } from '@core/utils/logger'
|
|
9
9
|
import { validateAuthSync, type CryptoAuthUser } from './helpers'
|
|
10
10
|
|
|
11
11
|
export interface CryptoAuthMiddlewareOptions {
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { Elysia } from 'elysia'
|
|
7
|
-
import { createGuard } from '
|
|
8
|
-
import type { Logger } from '
|
|
7
|
+
import { createGuard } from '@core/server/middleware/elysia-helpers'
|
|
8
|
+
import type { Logger } from '@core/utils/logger'
|
|
9
9
|
import { validateAuthSync } from './helpers'
|
|
10
10
|
|
|
11
11
|
export interface CryptoAuthMiddlewareOptions {
|