create-fluxstack 1.12.1 → 1.14.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.
- package/LLMD/INDEX.md +8 -1
- package/LLMD/agent.md +867 -0
- package/LLMD/config/environment-vars.md +30 -0
- package/LLMD/patterns/anti-patterns.md +100 -0
- package/LLMD/reference/routing.md +39 -39
- package/LLMD/resources/live-auth.md +465 -0
- package/LLMD/resources/live-components.md +168 -26
- package/LLMD/resources/live-logging.md +220 -0
- package/LLMD/resources/live-upload.md +59 -8
- package/LLMD/resources/rest-auth.md +290 -0
- package/README.md +520 -340
- package/app/client/index.html +2 -2
- package/app/client/public/favicon.svg +46 -0
- package/app/client/src/App.tsx +13 -1
- package/app/client/src/assets/fluxstack-static.svg +46 -0
- package/app/client/src/assets/fluxstack.svg +183 -0
- package/app/client/src/components/AppLayout.tsx +139 -9
- package/app/client/src/components/BackButton.tsx +13 -13
- package/app/client/src/components/DemoPage.tsx +4 -4
- package/app/client/src/live/AuthDemo.tsx +334 -0
- package/app/client/src/live/ChatDemo.tsx +2 -2
- package/app/client/src/live/CounterDemo.tsx +12 -12
- package/app/client/src/live/FormDemo.tsx +2 -2
- package/app/client/src/live/LiveDebuggerPanel.tsx +779 -0
- package/app/client/src/live/RoomChatDemo.tsx +24 -16
- package/app/client/src/main.tsx +13 -13
- package/app/client/src/pages/ApiTestPage.tsx +6 -6
- package/app/client/src/pages/HomePage.tsx +80 -52
- package/app/server/auth/AuthManager.ts +213 -0
- package/app/server/auth/DevAuthProvider.ts +66 -0
- package/app/server/auth/HashManager.ts +123 -0
- package/app/server/auth/JWTAuthProvider.example.ts +101 -0
- package/app/server/auth/RateLimiter.ts +106 -0
- package/app/server/auth/contracts.ts +192 -0
- package/app/server/auth/guards/SessionGuard.ts +167 -0
- package/app/server/auth/guards/TokenGuard.ts +202 -0
- package/app/server/auth/index.ts +174 -0
- package/app/server/auth/middleware.ts +163 -0
- package/app/server/auth/providers/InMemoryProvider.ts +162 -0
- package/app/server/auth/sessions/SessionManager.ts +164 -0
- package/app/server/cache/CacheManager.ts +81 -0
- package/app/server/cache/MemoryDriver.ts +112 -0
- package/app/server/cache/contracts.ts +49 -0
- package/app/server/cache/index.ts +42 -0
- package/app/server/index.ts +14 -0
- package/app/server/live/LiveAdminPanel.ts +174 -0
- package/app/server/live/LiveChat.ts +78 -77
- package/app/server/live/LiveCounter.ts +1 -0
- package/app/server/live/LiveForm.ts +1 -0
- package/app/server/live/LiveLocalCounter.ts +38 -32
- package/app/server/live/LiveProtectedChat.ts +151 -0
- package/app/server/live/LiveRoomChat.ts +1 -0
- package/app/server/live/LiveUpload.ts +1 -0
- package/app/server/live/register-components.ts +19 -19
- package/app/server/routes/auth.routes.ts +278 -0
- package/app/server/routes/index.ts +2 -0
- package/config/index.ts +8 -0
- package/config/system/auth.config.ts +49 -0
- package/config/system/runtime.config.ts +4 -0
- package/config/system/session.config.ts +33 -0
- package/core/build/optimizer.ts +235 -235
- package/core/client/LiveComponentsProvider.tsx +76 -5
- package/core/client/components/Live.tsx +17 -10
- package/core/client/components/LiveDebugger.tsx +1324 -0
- package/core/client/hooks/AdaptiveChunkSizer.ts +215 -215
- package/core/client/hooks/useLiveComponent.ts +58 -5
- package/core/client/hooks/useLiveDebugger.ts +392 -0
- package/core/client/index.ts +16 -1
- package/core/framework/server.ts +36 -4
- package/core/plugins/built-in/index.ts +134 -134
- package/core/plugins/built-in/live-components/commands/create-live-component.ts +19 -8
- package/core/plugins/built-in/monitoring/index.ts +10 -3
- package/core/plugins/built-in/vite/index.ts +151 -20
- package/core/plugins/config.ts +5 -4
- package/core/plugins/discovery.ts +11 -2
- package/core/plugins/manager.ts +11 -5
- package/core/plugins/module-resolver.ts +1 -1
- package/core/plugins/registry.ts +53 -25
- package/core/server/index.ts +15 -15
- package/core/server/live/ComponentRegistry.ts +134 -50
- package/core/server/live/FileUploadManager.ts +188 -24
- package/core/server/live/LiveComponentPerformanceMonitor.ts +9 -8
- package/core/server/live/LiveDebugger.ts +462 -0
- package/core/server/live/LiveLogger.ts +144 -0
- package/core/server/live/LiveRoomManager.ts +22 -5
- package/core/server/live/StateSignature.ts +704 -643
- package/core/server/live/WebSocketConnectionManager.ts +11 -10
- package/core/server/live/auth/LiveAuthContext.ts +71 -0
- package/core/server/live/auth/LiveAuthManager.ts +304 -0
- package/core/server/live/auth/index.ts +19 -0
- package/core/server/live/auth/types.ts +179 -0
- package/core/server/live/auto-generated-components.ts +8 -2
- package/core/server/live/index.ts +16 -0
- package/core/server/live/websocket-plugin.ts +323 -22
- package/core/server/plugins/static-files-plugin.ts +179 -69
- package/core/templates/create-project.ts +0 -3
- package/core/types/build.ts +219 -219
- package/core/types/plugin.ts +107 -107
- package/core/types/types.ts +278 -22
- package/core/utils/index.ts +17 -17
- package/core/utils/logger/index.ts +5 -2
- package/core/utils/logger/startup-banner.ts +82 -82
- package/core/utils/version.ts +6 -6
- package/package.json +1 -8
- package/plugins/crypto-auth/index.ts +6 -0
- package/plugins/crypto-auth/server/CryptoAuthLiveProvider.ts +58 -0
- package/plugins/crypto-auth/server/index.ts +24 -21
- package/rest-tests/README.md +57 -0
- package/rest-tests/auth-token.http +113 -0
- package/rest-tests/auth.http +112 -0
- package/rest-tests/rooms-token.http +69 -0
- package/rest-tests/users-token.http +62 -0
- package/.dockerignore +0 -81
- package/Dockerfile +0 -70
- package/LIVE_COMPONENTS_REVIEW.md +0 -781
- package/app/client/src/assets/react.svg +0 -1
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FluxStack Logger - Startup Banner
|
|
3
|
-
* Clean and beautiful startup display
|
|
4
|
-
*
|
|
5
|
-
* Developers can customize the banner by:
|
|
6
|
-
* 1. Setting showBanner: false in server config
|
|
7
|
-
* 2. Using displayStartupBanner() in app.listen() callback
|
|
8
|
-
* 3. Creating completely custom banners with chalk
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import chalk from 'chalk'
|
|
12
|
-
import { LOG } from './index'
|
|
13
|
-
import { FLUXSTACK_VERSION } from '../version'
|
|
14
|
-
|
|
15
|
-
export interface StartupInfo {
|
|
16
|
-
port: number
|
|
17
|
-
host?: string
|
|
18
|
-
apiPrefix?: string
|
|
19
|
-
environment: string
|
|
20
|
-
pluginCount?: number
|
|
21
|
-
vitePort?: number
|
|
22
|
-
viteEmbedded?: boolean // true when Vite runs programmatically with backend
|
|
23
|
-
swaggerPath?: string
|
|
24
|
-
liveComponents?: string[]
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Display clean startup banner
|
|
29
|
-
*/
|
|
30
|
-
export function displayStartupBanner(info: StartupInfo): void {
|
|
31
|
-
const {
|
|
32
|
-
port,
|
|
33
|
-
host = 'localhost',
|
|
34
|
-
apiPrefix = '/api',
|
|
35
|
-
environment,
|
|
36
|
-
pluginCount = 0,
|
|
37
|
-
vitePort,
|
|
38
|
-
viteEmbedded = false,
|
|
39
|
-
liveComponents = [],
|
|
40
|
-
} = info
|
|
41
|
-
|
|
42
|
-
// Build server URL
|
|
43
|
-
const displayHost = host === '0.0.0.0' ? 'localhost' : host
|
|
44
|
-
const serverUrl = `http://${displayHost}:${port}`
|
|
45
|
-
|
|
46
|
-
// Simple ready message with URL
|
|
47
|
-
console.log(chalk.green('\nServer ready!') + chalk.gray(` Environment: ${environment}${viteEmbedded ? ' | Vite: embedded' : ''}`))
|
|
48
|
-
console.log(chalk.cyan(` → ${serverUrl}`))
|
|
49
|
-
|
|
50
|
-
// Display Live Components
|
|
51
|
-
if (liveComponents.length > 0) {
|
|
52
|
-
console.log(chalk.gray(` Live Components (${liveComponents.length}): `) + chalk.yellow(liveComponents.join(', ')))
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Display plugins in compact format
|
|
56
|
-
const plugins = (global as any).__fluxstackPlugins || []
|
|
57
|
-
if (plugins.length > 0) {
|
|
58
|
-
const pluginList = plugins.map((p: any) => p.name).join(', ')
|
|
59
|
-
console.log(chalk.gray(` Plugins (${plugins.length}): `) + chalk.magenta(pluginList))
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
console.log('') // Empty line at the end
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Display simple plugin loaded message
|
|
67
|
-
*/
|
|
68
|
-
export function logPluginLoaded(name: string, version?: string): void {
|
|
69
|
-
const versionStr = version ? chalk.gray(`v${version}`) : ''
|
|
70
|
-
LOG(`${chalk.green('✓')} Plugin loaded: ${chalk.cyan(name)} ${versionStr}`)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Display plugin count summary
|
|
75
|
-
*/
|
|
76
|
-
export function logPluginsSummary(count: number): void {
|
|
77
|
-
if (count === 0) {
|
|
78
|
-
LOG(chalk.yellow('⚠ No plugins loaded'))
|
|
79
|
-
} else {
|
|
80
|
-
LOG(chalk.green(`✓ ${count} plugin${count > 1 ? 's' : ''} loaded successfully`))
|
|
81
|
-
}
|
|
82
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* FluxStack Logger - Startup Banner
|
|
3
|
+
* Clean and beautiful startup display
|
|
4
|
+
*
|
|
5
|
+
* Developers can customize the banner by:
|
|
6
|
+
* 1. Setting showBanner: false in server config
|
|
7
|
+
* 2. Using displayStartupBanner() in app.listen() callback
|
|
8
|
+
* 3. Creating completely custom banners with chalk
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import chalk from 'chalk'
|
|
12
|
+
import { LOG } from './index'
|
|
13
|
+
import { FLUXSTACK_VERSION } from '../version'
|
|
14
|
+
|
|
15
|
+
export interface StartupInfo {
|
|
16
|
+
port: number
|
|
17
|
+
host?: string
|
|
18
|
+
apiPrefix?: string
|
|
19
|
+
environment: string
|
|
20
|
+
pluginCount?: number
|
|
21
|
+
vitePort?: number
|
|
22
|
+
viteEmbedded?: boolean // true when Vite runs programmatically with backend
|
|
23
|
+
swaggerPath?: string
|
|
24
|
+
liveComponents?: string[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Display clean startup banner
|
|
29
|
+
*/
|
|
30
|
+
export function displayStartupBanner(info: StartupInfo): void {
|
|
31
|
+
const {
|
|
32
|
+
port,
|
|
33
|
+
host = 'localhost',
|
|
34
|
+
apiPrefix = '/api',
|
|
35
|
+
environment,
|
|
36
|
+
pluginCount = 0,
|
|
37
|
+
vitePort,
|
|
38
|
+
viteEmbedded = false,
|
|
39
|
+
liveComponents = [],
|
|
40
|
+
} = info
|
|
41
|
+
|
|
42
|
+
// Build server URL
|
|
43
|
+
const displayHost = host === '0.0.0.0' ? 'localhost' : host
|
|
44
|
+
const serverUrl = `http://${displayHost}:${port}`
|
|
45
|
+
|
|
46
|
+
// Simple ready message with URL
|
|
47
|
+
console.log(chalk.green('\nServer ready!') + chalk.gray(` Environment: ${environment}${viteEmbedded ? ' | Vite: embedded' : ''}`))
|
|
48
|
+
console.log(chalk.cyan(` → ${serverUrl}`))
|
|
49
|
+
|
|
50
|
+
// Display Live Components
|
|
51
|
+
if (liveComponents.length > 0) {
|
|
52
|
+
console.log(chalk.gray(` Live Components (${liveComponents.length}): `) + chalk.yellow(liveComponents.join(', ')))
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Display plugins in compact format
|
|
56
|
+
const plugins = (global as any).__fluxstackPlugins || []
|
|
57
|
+
if (plugins.length > 0) {
|
|
58
|
+
const pluginList = plugins.map((p: any) => p.name).join(', ')
|
|
59
|
+
console.log(chalk.gray(` Plugins (${plugins.length}): `) + chalk.magenta(pluginList))
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log('') // Empty line at the end
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Display simple plugin loaded message
|
|
67
|
+
*/
|
|
68
|
+
export function logPluginLoaded(name: string, version?: string): void {
|
|
69
|
+
const versionStr = version ? chalk.gray(`v${version}`) : ''
|
|
70
|
+
LOG(`${chalk.green('✓')} Plugin loaded: ${chalk.cyan(name)} ${versionStr}`)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Display plugin count summary
|
|
75
|
+
*/
|
|
76
|
+
export function logPluginsSummary(count: number): void {
|
|
77
|
+
if (count === 0) {
|
|
78
|
+
LOG(chalk.yellow('⚠ No plugins loaded'))
|
|
79
|
+
} else {
|
|
80
|
+
LOG(chalk.green(`✓ ${count} plugin${count > 1 ? 's' : ''} loaded successfully`))
|
|
81
|
+
}
|
|
82
|
+
}
|
package/core/utils/version.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FluxStack Framework Version
|
|
3
|
-
* Single source of truth for version number
|
|
4
|
-
* Auto-synced with package.json
|
|
5
|
-
*/
|
|
6
|
-
export const FLUXSTACK_VERSION = '1.
|
|
1
|
+
/**
|
|
2
|
+
* FluxStack Framework Version
|
|
3
|
+
* Single source of truth for version number
|
|
4
|
+
* Auto-synced with package.json
|
|
5
|
+
*/
|
|
6
|
+
export const FLUXSTACK_VERSION = '1.14.0'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-fluxstack",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "⚡ Revolutionary full-stack TypeScript framework with Declarative Config System, Elysia + React + Bun",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -55,7 +55,6 @@
|
|
|
55
55
|
"@types/react-dom": "^19.1.6",
|
|
56
56
|
"@vitest/coverage-v8": "^3.2.4",
|
|
57
57
|
"@vitest/ui": "^3.2.4",
|
|
58
|
-
"concurrently": "^9.2.0",
|
|
59
58
|
"cross-env": "^10.1.0",
|
|
60
59
|
"eslint": "^9.30.1",
|
|
61
60
|
"eslint-plugin-react-hooks": "^5.2.0",
|
|
@@ -73,16 +72,11 @@
|
|
|
73
72
|
"dependencies": {
|
|
74
73
|
"@elysiajs/eden": "^1.3.2",
|
|
75
74
|
"@elysiajs/swagger": "^1.3.1",
|
|
76
|
-
"@types/http-proxy-middleware": "^1.0.0",
|
|
77
|
-
"@types/ws": "^8.18.1",
|
|
78
75
|
"@vitejs/plugin-react": "^4.6.0",
|
|
79
76
|
"chalk": "^5.3.0",
|
|
80
|
-
"chokidar": "^4.0.3",
|
|
81
77
|
"commander": "^12.1.0",
|
|
82
78
|
"elysia": "^1.4.6",
|
|
83
|
-
"http-proxy-middleware": "^3.0.5",
|
|
84
79
|
"lightningcss": "^1.30.1",
|
|
85
|
-
"lucide-react": "^0.544.0",
|
|
86
80
|
"ora": "^8.1.0",
|
|
87
81
|
"react": "^19.1.0",
|
|
88
82
|
"react-dom": "^19.1.0",
|
|
@@ -92,7 +86,6 @@
|
|
|
92
86
|
"vite": "^7.1.7",
|
|
93
87
|
"winston": "^3.18.3",
|
|
94
88
|
"winston-daily-rotate-file": "^5.0.0",
|
|
95
|
-
"ws": "^8.18.3",
|
|
96
89
|
"zustand": "^5.0.8"
|
|
97
90
|
},
|
|
98
91
|
"engines": {
|
|
@@ -8,6 +8,8 @@ import type { FluxStack, PluginContext, RequestContext, ResponseContext } from "
|
|
|
8
8
|
type Plugin = FluxStack.Plugin
|
|
9
9
|
import { Elysia, t } from "elysia"
|
|
10
10
|
import { CryptoAuthService, AuthMiddleware } from "./server"
|
|
11
|
+
import { CryptoAuthLiveProvider } from "./server/CryptoAuthLiveProvider"
|
|
12
|
+
import { liveAuthManager } from "@core/server/live/auth"
|
|
11
13
|
import { makeProtectedRouteCommand } from "./cli/make-protected-route.command"
|
|
12
14
|
|
|
13
15
|
// ✅ Plugin carrega sua própria configuração (da pasta config/ do plugin)
|
|
@@ -88,6 +90,10 @@ export const cryptoAuthPlugin: Plugin = {
|
|
|
88
90
|
;(global as any).cryptoAuthService = authService
|
|
89
91
|
;(global as any).cryptoAuthMiddleware = authMiddleware
|
|
90
92
|
|
|
93
|
+
// 🔒 Register as LiveAuthProvider for Live Components WebSocket auth
|
|
94
|
+
liveAuthManager.register(new CryptoAuthLiveProvider(authService))
|
|
95
|
+
context.logger.info('🔒 Crypto Auth registered as Live Components auth provider')
|
|
96
|
+
|
|
91
97
|
// Store plugin info for table display
|
|
92
98
|
if (!(global as any).__fluxstackPlugins) {
|
|
93
99
|
(global as any).__fluxstackPlugins = []
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// 🔒 CryptoAuth → LiveAuthProvider Adapter
|
|
2
|
+
//
|
|
3
|
+
// Integra o plugin crypto-auth com o sistema de autenticação de Live Components.
|
|
4
|
+
// Permite usar autenticação Ed25519 em componentes real-time.
|
|
5
|
+
//
|
|
6
|
+
// Uso:
|
|
7
|
+
// import { CryptoAuthLiveProvider } from '@plugins/crypto-auth/server/CryptoAuthLiveProvider'
|
|
8
|
+
// import { liveAuthManager } from '@core/server/live/auth'
|
|
9
|
+
//
|
|
10
|
+
// liveAuthManager.register(new CryptoAuthLiveProvider(cryptoAuthService))
|
|
11
|
+
|
|
12
|
+
import type { CryptoAuthService } from './CryptoAuthService'
|
|
13
|
+
import type {
|
|
14
|
+
LiveAuthProvider,
|
|
15
|
+
LiveAuthCredentials,
|
|
16
|
+
LiveAuthContext,
|
|
17
|
+
} from '@core/server/live/auth/types'
|
|
18
|
+
import { AuthenticatedContext, ANONYMOUS_CONTEXT } from '@core/server/live/auth/LiveAuthContext'
|
|
19
|
+
|
|
20
|
+
export class CryptoAuthLiveProvider implements LiveAuthProvider {
|
|
21
|
+
readonly name = 'crypto-auth'
|
|
22
|
+
private authService: CryptoAuthService
|
|
23
|
+
|
|
24
|
+
constructor(authService: CryptoAuthService) {
|
|
25
|
+
this.authService = authService
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async authenticate(credentials: LiveAuthCredentials): Promise<LiveAuthContext | null> {
|
|
29
|
+
const { publicKey, signature, timestamp, nonce } = credentials
|
|
30
|
+
|
|
31
|
+
// Sem credenciais crypto = não autenticado
|
|
32
|
+
if (!publicKey || !signature) {
|
|
33
|
+
return null
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const result = await this.authService.validateRequest({
|
|
37
|
+
publicKey: publicKey as string,
|
|
38
|
+
timestamp: (timestamp as number) || Date.now(),
|
|
39
|
+
nonce: (nonce as string) || '',
|
|
40
|
+
signature: signature as string,
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
if (!result.success || !result.user) {
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return new AuthenticatedContext(
|
|
48
|
+
{
|
|
49
|
+
id: result.user.publicKey,
|
|
50
|
+
roles: result.user.isAdmin ? ['admin'] : ['user'],
|
|
51
|
+
permissions: result.user.permissions,
|
|
52
|
+
publicKey: result.user.publicKey,
|
|
53
|
+
isAdmin: result.user.isAdmin,
|
|
54
|
+
},
|
|
55
|
+
publicKey as string // token = publicKey
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -1,22 +1,25 @@
|
|
|
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
|
-
//
|
|
12
|
-
export {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
+
// LiveAuthProvider adapter for Live Components
|
|
12
|
+
export { CryptoAuthLiveProvider } from './CryptoAuthLiveProvider'
|
|
13
|
+
|
|
14
|
+
// Middlewares Elysia
|
|
15
|
+
export {
|
|
16
|
+
cryptoAuthRequired,
|
|
17
|
+
cryptoAuthAdmin,
|
|
18
|
+
cryptoAuthPermissions,
|
|
19
|
+
cryptoAuthOptional,
|
|
20
|
+
getCryptoAuthUser,
|
|
21
|
+
isCryptoAuthAuthenticated,
|
|
22
|
+
isCryptoAuthAdmin,
|
|
23
|
+
hasCryptoAuthPermission
|
|
24
|
+
} from './middlewares'
|
|
22
25
|
export type { CryptoAuthUser, CryptoAuthMiddlewareOptions } from './middlewares'
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# REST Tests
|
|
2
|
+
|
|
3
|
+
Arquivos `.http` para teste manual das APIs usando a extensão [REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) do VSCode.
|
|
4
|
+
|
|
5
|
+
## Requisitos
|
|
6
|
+
|
|
7
|
+
- **VSCode** com extensão **REST Client** (`humao.rest-client`)
|
|
8
|
+
- **Servidor rodando**: `bun run dev`
|
|
9
|
+
|
|
10
|
+
## Arquivos
|
|
11
|
+
|
|
12
|
+
| Arquivo | Guard | Descrição |
|
|
13
|
+
|---------|-------|-----------|
|
|
14
|
+
| `auth.http` | Session (cookie) | Register, Login, Me, Logout |
|
|
15
|
+
| `auth-token.http` | Token (Bearer) | Register, Login, Me, Logout |
|
|
16
|
+
| `users-token.http` | Token (Bearer) | CRUD de usuários |
|
|
17
|
+
| `rooms-token.http` | Token (Bearer) | Mensagens e eventos de salas |
|
|
18
|
+
|
|
19
|
+
## Configuração do Guard
|
|
20
|
+
|
|
21
|
+
Os arquivos `*-token.http` requerem o guard de token. Configure no `.env`:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
AUTH_DEFAULT_GUARD=token
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Os arquivos sem sufixo usam o guard de sessão (padrão).
|
|
28
|
+
|
|
29
|
+
## Como usar
|
|
30
|
+
|
|
31
|
+
1. Abra qualquer arquivo `.http` no VSCode
|
|
32
|
+
2. Clique em **"Send Request"** acima de cada bloco `###`
|
|
33
|
+
3. O response aparece numa aba lateral
|
|
34
|
+
|
|
35
|
+
## Fluxo de teste (Token)
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
1. GET /api/health → Verificar servidor
|
|
39
|
+
2. POST /api/auth/register → Criar usuário (retorna token)
|
|
40
|
+
3. POST /api/auth/login → Login (retorna token)
|
|
41
|
+
4. GET /api/auth/me → Bearer token no header
|
|
42
|
+
5. POST /api/auth/logout → Revogar token
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
> **Dica**: Nos arquivos `*-token.http`, o token do login é capturado automaticamente via `@name login` e injetado nos requests seguintes com `{{login.response.body.token}}`.
|
|
46
|
+
|
|
47
|
+
## Fluxo de teste (Session)
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
1. GET /api/health → Verificar servidor
|
|
51
|
+
2. POST /api/auth/register → Criar usuário
|
|
52
|
+
3. POST /api/auth/login → Obter cookie de sessão
|
|
53
|
+
4. GET /api/auth/me → Usar cookie para ver perfil
|
|
54
|
+
5. POST /api/auth/logout → Encerrar sessão
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
> **Dica**: Após o login, copie o valor do cookie `fluxstack_session` do response e cole nos requests que precisam de autenticação.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
@base = http://localhost:3000/api
|
|
2
|
+
|
|
3
|
+
# =============================================
|
|
4
|
+
# Auth Tests - Bearer Token Guard
|
|
5
|
+
# =============================================
|
|
6
|
+
# Requer: AUTH_DEFAULT_GUARD=token no .env
|
|
7
|
+
# =============================================
|
|
8
|
+
|
|
9
|
+
### ===== Health Check =====
|
|
10
|
+
|
|
11
|
+
GET {{base}}/health
|
|
12
|
+
|
|
13
|
+
### ===== Register =====
|
|
14
|
+
# @name register
|
|
15
|
+
|
|
16
|
+
POST {{base}}/auth/register
|
|
17
|
+
Content-Type: application/json
|
|
18
|
+
|
|
19
|
+
{
|
|
20
|
+
"name": "John Doe",
|
|
21
|
+
"email": "john@example.com",
|
|
22
|
+
"password": "secret123"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
### ===== Register (duplicado - 422) =====
|
|
26
|
+
|
|
27
|
+
POST {{base}}/auth/register
|
|
28
|
+
Content-Type: application/json
|
|
29
|
+
|
|
30
|
+
{
|
|
31
|
+
"name": "Jane Doe",
|
|
32
|
+
"email": "john@example.com",
|
|
33
|
+
"password": "other123"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
### ===== Register (campos faltando - 422) =====
|
|
37
|
+
|
|
38
|
+
POST {{base}}/auth/register
|
|
39
|
+
Content-Type: application/json
|
|
40
|
+
|
|
41
|
+
{
|
|
42
|
+
"name": "No Email"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
### ===== Register (senha curta - 422) =====
|
|
46
|
+
|
|
47
|
+
POST {{base}}/auth/register
|
|
48
|
+
Content-Type: application/json
|
|
49
|
+
|
|
50
|
+
{
|
|
51
|
+
"name": "Short Pass",
|
|
52
|
+
"email": "short@example.com",
|
|
53
|
+
"password": "12"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
### ===== Login =====
|
|
57
|
+
# @name login
|
|
58
|
+
|
|
59
|
+
POST {{base}}/auth/login
|
|
60
|
+
Content-Type: application/json
|
|
61
|
+
|
|
62
|
+
{
|
|
63
|
+
"email": "john@example.com",
|
|
64
|
+
"password": "secret123"
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
### ===== Login (senha errada - 401) =====
|
|
68
|
+
|
|
69
|
+
POST {{base}}/auth/login
|
|
70
|
+
Content-Type: application/json
|
|
71
|
+
|
|
72
|
+
{
|
|
73
|
+
"email": "john@example.com",
|
|
74
|
+
"password": "wrong-password"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
### ===== Login (email desconhecido - 401) =====
|
|
78
|
+
|
|
79
|
+
POST {{base}}/auth/login
|
|
80
|
+
Content-Type: application/json
|
|
81
|
+
|
|
82
|
+
{
|
|
83
|
+
"email": "unknown@example.com",
|
|
84
|
+
"password": "secret123"
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
### ===== Me (sem token - 401) =====
|
|
88
|
+
|
|
89
|
+
GET {{base}}/auth/me
|
|
90
|
+
|
|
91
|
+
### ===== Me (com Bearer token) =====
|
|
92
|
+
|
|
93
|
+
GET {{base}}/auth/me
|
|
94
|
+
Authorization: Bearer {{login.response.body.token}}
|
|
95
|
+
|
|
96
|
+
### ===== Me (token inválido - 401) =====
|
|
97
|
+
|
|
98
|
+
GET {{base}}/auth/me
|
|
99
|
+
Authorization: Bearer token-invalido-123
|
|
100
|
+
|
|
101
|
+
### ===== Logout (sem token - 401) =====
|
|
102
|
+
|
|
103
|
+
POST {{base}}/auth/logout
|
|
104
|
+
|
|
105
|
+
### ===== Logout (com Bearer token) =====
|
|
106
|
+
|
|
107
|
+
POST {{base}}/auth/logout
|
|
108
|
+
Authorization: Bearer {{login.response.body.token}}
|
|
109
|
+
|
|
110
|
+
### ===== Me após logout (token revogado - 401) =====
|
|
111
|
+
|
|
112
|
+
GET {{base}}/auth/me
|
|
113
|
+
Authorization: Bearer {{login.response.body.token}}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
@base = http://localhost:3000/api
|
|
2
|
+
|
|
3
|
+
### ===== Health Check =====
|
|
4
|
+
|
|
5
|
+
GET {{base}}/health
|
|
6
|
+
|
|
7
|
+
### ===== Register =====
|
|
8
|
+
|
|
9
|
+
POST {{base}}/auth/register
|
|
10
|
+
Content-Type: application/json
|
|
11
|
+
|
|
12
|
+
{
|
|
13
|
+
"name": "John Doe",
|
|
14
|
+
"email": "john@example.com",
|
|
15
|
+
"password": "secret123"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
### ===== Register (duplicate - should return 422) =====
|
|
19
|
+
|
|
20
|
+
POST {{base}}/auth/register
|
|
21
|
+
Content-Type: application/json
|
|
22
|
+
|
|
23
|
+
{
|
|
24
|
+
"name": "Jane Doe",
|
|
25
|
+
"email": "john@example.com",
|
|
26
|
+
"password": "other123"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
### ===== Register (missing fields - should return 422) =====
|
|
30
|
+
|
|
31
|
+
POST {{base}}/auth/register
|
|
32
|
+
Content-Type: application/json
|
|
33
|
+
|
|
34
|
+
{
|
|
35
|
+
"name": "No Email"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
### ===== Register (short password - should return 422) =====
|
|
39
|
+
|
|
40
|
+
POST {{base}}/auth/register
|
|
41
|
+
Content-Type: application/json
|
|
42
|
+
|
|
43
|
+
{
|
|
44
|
+
"name": "Short Pass",
|
|
45
|
+
"email": "short@example.com",
|
|
46
|
+
"password": "12"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
### ===== Login =====
|
|
50
|
+
|
|
51
|
+
# @name login
|
|
52
|
+
POST {{base}}/auth/login
|
|
53
|
+
Content-Type: application/json
|
|
54
|
+
|
|
55
|
+
{
|
|
56
|
+
"email": "john@example.com",
|
|
57
|
+
"password": "secret123"
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
### ===== Login (wrong password - should return 401) =====
|
|
61
|
+
|
|
62
|
+
POST {{base}}/auth/login
|
|
63
|
+
Content-Type: application/json
|
|
64
|
+
|
|
65
|
+
{
|
|
66
|
+
"email": "john@example.com",
|
|
67
|
+
"password": "wrong-password"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
### ===== Login (unknown email - should return 401) =====
|
|
71
|
+
|
|
72
|
+
POST {{base}}/auth/login
|
|
73
|
+
Content-Type: application/json
|
|
74
|
+
|
|
75
|
+
{
|
|
76
|
+
"email": "unknown@example.com",
|
|
77
|
+
"password": "secret123"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
### ===== Me (no auth - should return 401) =====
|
|
81
|
+
|
|
82
|
+
GET {{base}}/auth/me
|
|
83
|
+
|
|
84
|
+
### ===== Me (with session cookie) =====
|
|
85
|
+
# Copy the fluxstack_session cookie value from the login response above
|
|
86
|
+
|
|
87
|
+
GET {{base}}/auth/me
|
|
88
|
+
Cookie: fluxstack_session=PASTE_SESSION_COOKIE_HERE
|
|
89
|
+
|
|
90
|
+
### ===== Logout (no auth - should return 401) =====
|
|
91
|
+
|
|
92
|
+
POST {{base}}/auth/logout
|
|
93
|
+
|
|
94
|
+
### ===== Logout (with session cookie) =====
|
|
95
|
+
# Copy the fluxstack_session cookie value from the login response
|
|
96
|
+
|
|
97
|
+
POST {{base}}/auth/logout
|
|
98
|
+
Cookie: fluxstack_session=PASTE_SESSION_COOKIE_HERE
|
|
99
|
+
|
|
100
|
+
### ===== Users CRUD =====
|
|
101
|
+
|
|
102
|
+
GET {{base}}/users
|
|
103
|
+
|
|
104
|
+
###
|
|
105
|
+
|
|
106
|
+
POST {{base}}/users
|
|
107
|
+
Content-Type: application/json
|
|
108
|
+
|
|
109
|
+
{
|
|
110
|
+
"name": "Test User",
|
|
111
|
+
"email": "test@example.com"
|
|
112
|
+
}
|