create-fluxstack 1.5.0 → 1.5.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 (49) hide show
  1. package/.env.example +1 -8
  2. package/app/client/src/App.tsx +1 -4
  3. package/app/server/index.ts +0 -4
  4. package/app/server/routes/index.ts +1 -5
  5. package/config/index.ts +1 -9
  6. package/core/cli/generators/plugin.ts +34 -324
  7. package/core/cli/generators/template-engine.ts +0 -5
  8. package/core/cli/plugin-discovery.ts +12 -33
  9. package/core/framework/server.ts +0 -10
  10. package/core/plugins/dependency-manager.ts +22 -89
  11. package/core/plugins/index.ts +0 -4
  12. package/core/plugins/manager.ts +2 -3
  13. package/core/plugins/registry.ts +1 -28
  14. package/core/utils/logger/index.ts +0 -4
  15. package/fluxstack.config.ts +114 -253
  16. package/package.json +117 -117
  17. package/CRYPTO-AUTH-MIDDLEWARE-GUIDE.md +0 -475
  18. package/CRYPTO-AUTH-MIDDLEWARES.md +0 -473
  19. package/CRYPTO-AUTH-USAGE.md +0 -491
  20. package/EXEMPLO-ROTA-PROTEGIDA.md +0 -347
  21. package/QUICK-START-CRYPTO-AUTH.md +0 -221
  22. package/app/client/src/pages/CryptoAuthPage.tsx +0 -394
  23. package/app/server/routes/crypto-auth-demo.routes.ts +0 -167
  24. package/app/server/routes/example-with-crypto-auth.routes.ts +0 -235
  25. package/app/server/routes/exemplo-posts.routes.ts +0 -161
  26. package/core/plugins/module-resolver.ts +0 -216
  27. package/plugins/crypto-auth/README.md +0 -788
  28. package/plugins/crypto-auth/ai-context.md +0 -1282
  29. package/plugins/crypto-auth/cli/make-protected-route.command.ts +0 -383
  30. package/plugins/crypto-auth/client/CryptoAuthClient.ts +0 -302
  31. package/plugins/crypto-auth/client/components/AuthProvider.tsx +0 -131
  32. package/plugins/crypto-auth/client/components/LoginButton.tsx +0 -138
  33. package/plugins/crypto-auth/client/components/ProtectedRoute.tsx +0 -89
  34. package/plugins/crypto-auth/client/components/index.ts +0 -12
  35. package/plugins/crypto-auth/client/index.ts +0 -12
  36. package/plugins/crypto-auth/config/index.ts +0 -34
  37. package/plugins/crypto-auth/index.ts +0 -162
  38. package/plugins/crypto-auth/package.json +0 -66
  39. package/plugins/crypto-auth/server/AuthMiddleware.ts +0 -181
  40. package/plugins/crypto-auth/server/CryptoAuthService.ts +0 -186
  41. package/plugins/crypto-auth/server/index.ts +0 -22
  42. package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +0 -65
  43. package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +0 -26
  44. package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +0 -76
  45. package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +0 -45
  46. package/plugins/crypto-auth/server/middlewares/helpers.ts +0 -140
  47. package/plugins/crypto-auth/server/middlewares/index.ts +0 -22
  48. package/plugins/crypto-auth/server/middlewares.ts +0 -19
  49. package/test-crypto-auth.ts +0 -101
@@ -1,347 +0,0 @@
1
- # 🔐 Como Criar Rotas com Crypto-Auth
2
-
3
- Guia prático para desenvolvedores criarem rotas usando o sistema de autenticação.
4
-
5
- ## 📋 Passo a Passo
6
-
7
- ### 1️⃣ Criar Arquivo de Rotas
8
-
9
- Crie um arquivo em `app/server/routes/`:
10
-
11
- ```typescript
12
- // app/server/routes/posts.routes.ts
13
- import { Elysia, t } from 'elysia'
14
- import {
15
- cryptoAuthRequired,
16
- cryptoAuthAdmin,
17
- cryptoAuthOptional,
18
- getCryptoAuthUser
19
- } from '@/plugins/crypto-auth/server'
20
-
21
- export const postsRoutes = new Elysia({ prefix: '/posts' })
22
-
23
- // ========================================
24
- // 🌐 ROTA PÚBLICA - Qualquer um pode acessar
25
- // ========================================
26
- .get('/', () => {
27
- return {
28
- success: true,
29
- posts: [
30
- { id: 1, title: 'Post público' },
31
- { id: 2, title: 'Outro post' }
32
- ]
33
- }
34
- })
35
-
36
- // ========================================
37
- // 🔒 ROTA PROTEGIDA - Requer autenticação
38
- // ========================================
39
- .guard({}, (app) =>
40
- app.use(cryptoAuthRequired())
41
-
42
- // GET /api/posts/my-posts - Lista posts do usuário autenticado
43
- .get('/my-posts', ({ request }) => {
44
- const user = getCryptoAuthUser(request)!
45
-
46
- return {
47
- success: true,
48
- message: `Posts de ${user.publicKey.substring(0, 8)}...`,
49
- posts: [
50
- { id: 1, title: 'Meu post privado', author: user.publicKey }
51
- ]
52
- }
53
- })
54
-
55
- // POST /api/posts - Criar novo post (autenticação obrigatória)
56
- .post('/', ({ request, body }) => {
57
- const user = getCryptoAuthUser(request)!
58
- const { title, content } = body as { title: string; content: string }
59
-
60
- return {
61
- success: true,
62
- message: 'Post criado com sucesso',
63
- post: {
64
- id: Date.now(),
65
- title,
66
- content,
67
- author: user.publicKey,
68
- createdAt: new Date().toISOString()
69
- }
70
- }
71
- }, {
72
- body: t.Object({
73
- title: t.String(),
74
- content: t.String()
75
- })
76
- })
77
- )
78
-
79
- // ========================================
80
- // 👑 ROTA ADMIN - Apenas administradores
81
- // ========================================
82
- .guard({}, (app) =>
83
- app.use(cryptoAuthAdmin())
84
-
85
- // DELETE /api/posts/:id - Deletar qualquer post (só admin)
86
- .delete('/:id', ({ request, params }) => {
87
- const user = getCryptoAuthUser(request)!
88
-
89
- return {
90
- success: true,
91
- message: `Post ${params.id} deletado por admin`,
92
- deletedBy: user.publicKey.substring(0, 8) + '...'
93
- }
94
- })
95
-
96
- // GET /api/posts/moderation - Painel de moderação
97
- .get('/moderation', ({ request }) => {
98
- const user = getCryptoAuthUser(request)!
99
-
100
- return {
101
- success: true,
102
- message: 'Painel de moderação',
103
- admin: user.publicKey.substring(0, 8) + '...',
104
- pendingPosts: [],
105
- reportedPosts: []
106
- }
107
- })
108
- )
109
-
110
- // ========================================
111
- // 🌓 ROTA COM AUTH OPCIONAL - Funciona com/sem auth
112
- // ========================================
113
- .guard({}, (app) =>
114
- app.use(cryptoAuthOptional())
115
-
116
- // GET /api/posts/:id - Detalhes do post (conteúdo extra se autenticado)
117
- .get('/:id', ({ request, params }) => {
118
- const user = getCryptoAuthUser(request)
119
- const isAuthenticated = !!user
120
-
121
- return {
122
- success: true,
123
- post: {
124
- id: params.id,
125
- title: 'Post de exemplo',
126
- content: 'Conteúdo público',
127
- // ✅ Conteúdo extra apenas para autenticados
128
- extraContent: isAuthenticated
129
- ? 'Conteúdo premium para usuários autenticados'
130
- : null,
131
- canEdit: isAuthenticated,
132
- viewer: user ? user.publicKey.substring(0, 8) + '...' : 'anonymous'
133
- }
134
- }
135
- })
136
- )
137
- ```
138
-
139
- ### 2️⃣ Registrar no Router Principal
140
-
141
- ```typescript
142
- // app/server/routes/index.ts
143
- import { Elysia } from 'elysia'
144
- import { postsRoutes } from './posts.routes' // ✅ Importar suas rotas
145
-
146
- export const apiRoutes = new Elysia({ prefix: '/api' })
147
- .use(userRoutes)
148
- .use(postsRoutes) // ✅ Adicionar aqui
149
- // ... outras rotas
150
- ```
151
-
152
- ### 3️⃣ Como o Cliente Faz Login
153
-
154
- O cliente precisa enviar headers de autenticação criptográfica:
155
-
156
- ```typescript
157
- // Frontend/Cliente
158
- import { generateKeyPair, sign } from './crypto-utils'
159
-
160
- // 1. Gerar par de chaves (feito uma vez)
161
- const { publicKey, privateKey } = generateKeyPair()
162
-
163
- // 2. Fazer requisição autenticada
164
- const timestamp = Date.now()
165
- const nonce = crypto.randomUUID()
166
- const message = `GET:/api/posts/my-posts:${timestamp}:${nonce}`
167
- const signature = sign(message, privateKey)
168
-
169
- fetch('http://localhost:3000/api/posts/my-posts', {
170
- headers: {
171
- 'X-Public-Key': publicKey,
172
- 'X-Timestamp': timestamp.toString(),
173
- 'X-Nonce': nonce,
174
- 'X-Signature': signature
175
- }
176
- })
177
- ```
178
-
179
- ## 🧪 Testando as Rotas
180
-
181
- ### Rota Pública (sem auth)
182
- ```bash
183
- curl http://localhost:3000/api/posts
184
- # ✅ 200 OK
185
- ```
186
-
187
- ### Rota Protegida (sem auth)
188
- ```bash
189
- curl http://localhost:3000/api/posts/my-posts
190
- # ❌ 401 {"error": {"message": "Authentication required"}}
191
- ```
192
-
193
- ### Rota Protegida (com auth)
194
- ```bash
195
- curl http://localhost:3000/api/posts/my-posts \
196
- -H "X-Public-Key: abc123..." \
197
- -H "X-Timestamp: 1234567890" \
198
- -H "X-Nonce: uuid-here" \
199
- -H "X-Signature: signature-here"
200
- # ✅ 200 OK {"posts": [...]}
201
- ```
202
-
203
- ### Rota Admin (sem admin)
204
- ```bash
205
- curl http://localhost:3000/api/posts/moderation \
206
- -H "X-Public-Key: user-key..." \
207
- # ... outros headers
208
- # ❌ 403 {"error": {"message": "Admin privileges required"}}
209
- ```
210
-
211
- ### Rota Opcional (ambos funcionam)
212
- ```bash
213
- # Sem auth
214
- curl http://localhost:3000/api/posts/123
215
- # ✅ 200 OK {"post": {"extraContent": null}}
216
-
217
- # Com auth
218
- curl http://localhost:3000/api/posts/123 -H "X-Public-Key: ..."
219
- # ✅ 200 OK {"post": {"extraContent": "Conteúdo premium..."}}
220
- ```
221
-
222
- ## 📦 Middlewares Disponíveis
223
-
224
- ### `cryptoAuthRequired()`
225
- Bloqueia acesso se não autenticado.
226
- ```typescript
227
- .use(cryptoAuthRequired())
228
- .get('/protected', ({ request }) => {
229
- const user = getCryptoAuthUser(request)! // ✅ Sempre existe
230
- })
231
- ```
232
-
233
- ### `cryptoAuthAdmin()`
234
- Bloqueia se não for admin.
235
- ```typescript
236
- .use(cryptoAuthAdmin())
237
- .delete('/users/:id', ({ request }) => {
238
- const user = getCryptoAuthUser(request)! // ✅ Sempre admin
239
- })
240
- ```
241
-
242
- ### `cryptoAuthOptional()`
243
- Adiciona user se autenticado, mas não bloqueia.
244
- ```typescript
245
- .use(cryptoAuthOptional())
246
- .get('/feed', ({ request }) => {
247
- const user = getCryptoAuthUser(request) // ⚠️ Pode ser null
248
- if (user) {
249
- return { message: 'Feed personalizado' }
250
- }
251
- return { message: 'Feed público' }
252
- })
253
- ```
254
-
255
- ### `cryptoAuthPermissions(['write', 'delete'])`
256
- Bloqueia se não tiver permissões específicas.
257
- ```typescript
258
- .use(cryptoAuthPermissions(['write', 'delete']))
259
- .put('/posts/:id', ({ request }) => {
260
- const user = getCryptoAuthUser(request)! // ✅ Tem as permissões
261
- })
262
- ```
263
-
264
- ## 🔑 Helpers Úteis
265
-
266
- ```typescript
267
- import {
268
- getCryptoAuthUser,
269
- isCryptoAuthAuthenticated,
270
- isCryptoAuthAdmin,
271
- hasCryptoAuthPermission
272
- } from '@/plugins/crypto-auth/server'
273
-
274
- // Dentro de uma rota
275
- ({ request }) => {
276
- // Pegar usuário autenticado (null se não autenticado)
277
- const user = getCryptoAuthUser(request)
278
-
279
- // Verificar se está autenticado
280
- if (!isCryptoAuthAuthenticated(request)) {
281
- return { error: 'Login required' }
282
- }
283
-
284
- // Verificar se é admin
285
- if (isCryptoAuthAdmin(request)) {
286
- return { message: 'Admin panel' }
287
- }
288
-
289
- // Verificar permissão específica
290
- if (hasCryptoAuthPermission(request, 'delete')) {
291
- return { message: 'Can delete' }
292
- }
293
- }
294
- ```
295
-
296
- ## ⚠️ Boas Práticas
297
-
298
- ### ✅ Fazer
299
- - Usar `.guard({})` para isolar middlewares
300
- - Verificar `null` em rotas com `cryptoAuthOptional()`
301
- - Usar `!` apenas após middlewares obrigatórios
302
- - Separar rotas por nível de permissão
303
-
304
- ### ❌ Não Fazer
305
- - Usar `.use()` fora de `.guard()` (afeta TODAS as rotas seguintes)
306
- - Esquecer `.as('plugin')` ao criar middlewares customizados
307
- - Assumir que `user` existe sem middleware de proteção
308
-
309
- ## 🎯 Padrão Recomendado
310
-
311
- ```typescript
312
- export const myRoutes = new Elysia({ prefix: '/my-feature' })
313
-
314
- // Públicas primeiro
315
- .get('/public', () => ({ ... }))
316
-
317
- // Auth opcional (separado)
318
- .guard({}, (app) =>
319
- app.use(cryptoAuthOptional())
320
- .get('/optional', ({ request }) => {
321
- const user = getCryptoAuthUser(request)
322
- // ...
323
- })
324
- )
325
-
326
- // Protegidas (separado)
327
- .guard({}, (app) =>
328
- app.use(cryptoAuthRequired())
329
- .get('/protected', ({ request }) => {
330
- const user = getCryptoAuthUser(request)!
331
- // ...
332
- })
333
- )
334
-
335
- // Admin (separado)
336
- .guard({}, (app) =>
337
- app.use(cryptoAuthAdmin())
338
- .delete('/admin-only', ({ request }) => {
339
- const user = getCryptoAuthUser(request)!
340
- // ...
341
- })
342
- )
343
- ```
344
-
345
- ---
346
-
347
- **Pronto!** Agora você sabe criar rotas com autenticação crypto-auth no FluxStack. 🚀
@@ -1,221 +0,0 @@
1
- # ⚡ Quick Start: Crypto-Auth em 5 Minutos
2
-
3
- ## 🎯 Como Criar uma Rota Protegida
4
-
5
- ### 🚀 Opção 1: CLI (Recomendado)
6
-
7
- Use o comando `crypto-auth:make:route` para gerar rotas automaticamente:
8
-
9
- ```bash
10
- # Rota com autenticação obrigatória (padrão)
11
- bun flux crypto-auth:make:route users
12
-
13
- # Rota apenas para admins
14
- bun flux crypto-auth:make:route admin-panel --auth admin
15
-
16
- # Rota com autenticação opcional
17
- bun flux crypto-auth:make:route blog --auth optional
18
-
19
- # Rota pública (sem auth)
20
- bun flux crypto-auth:make:route public-api --auth public
21
- ```
22
-
23
- O comando cria automaticamente:
24
- - ✅ Arquivo de rotas em `app/server/routes/[nome].routes.ts`
25
- - ✅ Middlewares de autenticação configurados
26
- - ✅ Templates de CRUD completos
27
- - ✅ Exemplos de uso de `getCryptoAuthUser()`
28
-
29
- **Tipos de `--auth` disponíveis:**
30
- - `required` - Autenticação obrigatória (padrão)
31
- - `admin` - Apenas administradores
32
- - `optional` - Auth opcional (rota pública com conteúdo extra para autenticados)
33
- - `public` - Completamente pública (sem middleware)
34
-
35
- ---
36
-
37
- ### ⚙️ Opção 2: Manual
38
-
39
- #### 1️⃣ Criar Arquivo de Rotas
40
-
41
- ```typescript
42
- // app/server/routes/minhas-rotas.routes.ts
43
- import { Elysia } from 'elysia'
44
- import { cryptoAuthRequired, getCryptoAuthUser } from '@/plugins/crypto-auth/server'
45
-
46
- export const minhasRotas = new Elysia({ prefix: '/minhas-rotas' })
47
-
48
- // Rota pública
49
- .get('/publica', () => ({ message: 'Todos podem ver' }))
50
-
51
- // Rota protegida
52
- .guard({}, (app) =>
53
- app.use(cryptoAuthRequired())
54
- .get('/protegida', ({ request }) => {
55
- const user = getCryptoAuthUser(request)!
56
- return {
57
- message: 'Área restrita',
58
- user: user.publicKey.substring(0, 8) + '...'
59
- }
60
- })
61
- )
62
- ```
63
-
64
- #### 2️⃣ Registrar no Router
65
-
66
- ```typescript
67
- // app/server/routes/index.ts
68
- import { minhasRotas } from './minhas-rotas.routes'
69
-
70
- export const apiRoutes = new Elysia({ prefix: '/api' })
71
- .use(minhasRotas) // ✅ Adicionar aqui
72
- ```
73
-
74
- #### 3️⃣ Testar
75
-
76
- ```bash
77
- # Pública (funciona)
78
- curl http://localhost:3000/api/minhas-rotas/publica
79
- # ✅ {"message": "Todos podem ver"}
80
-
81
- # Protegida (sem auth)
82
- curl http://localhost:3000/api/minhas-rotas/protegida
83
- # ❌ {"error": {"message": "Authentication required", "code": "CRYPTO_AUTH_REQUIRED", "statusCode": 401}}
84
- ```
85
-
86
- ## 🔐 Tipos de Middleware
87
-
88
- ### `cryptoAuthRequired()` - Autenticação Obrigatória
89
- ```typescript
90
- .guard({}, (app) =>
91
- app.use(cryptoAuthRequired())
92
- .get('/protegida', ({ request }) => {
93
- const user = getCryptoAuthUser(request)! // ✅ Sempre existe
94
- return { user }
95
- })
96
- )
97
- ```
98
-
99
- ### `cryptoAuthAdmin()` - Apenas Administradores
100
- ```typescript
101
- .guard({}, (app) =>
102
- app.use(cryptoAuthAdmin())
103
- .delete('/deletar/:id', ({ request, params }) => {
104
- const user = getCryptoAuthUser(request)! // ✅ Sempre admin
105
- return { message: `${params.id} deletado` }
106
- })
107
- )
108
- ```
109
-
110
- ### `cryptoAuthOptional()` - Autenticação Opcional
111
- ```typescript
112
- .guard({}, (app) =>
113
- app.use(cryptoAuthOptional())
114
- .get('/feed', ({ request }) => {
115
- const user = getCryptoAuthUser(request) // ⚠️ Pode ser null
116
-
117
- if (user) {
118
- return { message: 'Feed personalizado', user }
119
- }
120
- return { message: 'Feed público' }
121
- })
122
- )
123
- ```
124
-
125
- ### `cryptoAuthPermissions([...])` - Permissões Específicas
126
- ```typescript
127
- .guard({}, (app) =>
128
- app.use(cryptoAuthPermissions(['write', 'delete']))
129
- .put('/editar/:id', ({ request }) => {
130
- const user = getCryptoAuthUser(request)! // ✅ Tem as permissões
131
- return { message: 'Editado' }
132
- })
133
- )
134
- ```
135
-
136
- ## 📊 Exemplo Real Funcionando
137
-
138
- Veja o arquivo criado: **`app/server/routes/exemplo-posts.routes.ts`**
139
-
140
- Rotas disponíveis:
141
- - ✅ `GET /api/exemplo-posts` - Pública
142
- - ✅ `GET /api/exemplo-posts/:id` - Auth opcional
143
- - ✅ `GET /api/exemplo-posts/meus-posts` - Protegida
144
- - ✅ `POST /api/exemplo-posts/criar` - Protegida
145
- - ✅ `GET /api/exemplo-posts/admin/todos` - Admin
146
- - ✅ `DELETE /api/exemplo-posts/admin/:id` - Admin
147
-
148
- ## 🧪 Testando Agora
149
-
150
- ```bash
151
- # Pública
152
- curl http://localhost:3000/api/exemplo-posts
153
- # ✅ {"success":true,"posts":[...]}
154
-
155
- # Auth opcional (sem auth)
156
- curl http://localhost:3000/api/exemplo-posts/1
157
- # ✅ {"success":true,"post":{"premiumContent":null,"viewer":"Visitante anônimo"}}
158
-
159
- # Protegida (sem auth)
160
- curl http://localhost:3000/api/exemplo-posts/meus-posts
161
- # ❌ {"error":{"message":"Authentication required"}}
162
-
163
- # Admin (sem auth)
164
- curl http://localhost:3000/api/exemplo-posts/admin/todos
165
- # ❌ {"error":{"message":"Authentication required"}}
166
- ```
167
-
168
- ## 🔑 Helpers Úteis
169
-
170
- ```typescript
171
- import {
172
- getCryptoAuthUser,
173
- isCryptoAuthAuthenticated,
174
- isCryptoAuthAdmin,
175
- hasCryptoAuthPermission
176
- } from '@/plugins/crypto-auth/server'
177
-
178
- ({ request }) => {
179
- const user = getCryptoAuthUser(request) // User | null
180
- const isAuth = isCryptoAuthAuthenticated(request) // boolean
181
- const isAdmin = isCryptoAuthAdmin(request) // boolean
182
- const canDelete = hasCryptoAuthPermission(request, 'delete') // boolean
183
- }
184
- ```
185
-
186
- ## ⚠️ Importante
187
-
188
- ### ✅ Fazer
189
- ```typescript
190
- // Isolar middlewares com .guard({})
191
- .guard({}, (app) =>
192
- app.use(cryptoAuthRequired())
193
- .get('/protected', () => {})
194
- )
195
-
196
- // Verificar null em auth opcional
197
- .guard({}, (app) =>
198
- app.use(cryptoAuthOptional())
199
- .get('/feed', ({ request }) => {
200
- const user = getCryptoAuthUser(request)
201
- if (user) { /* autenticado */ }
202
- })
203
- )
204
- ```
205
-
206
- ### ❌ Não Fazer
207
- ```typescript
208
- // ❌ Usar .use() sem .guard() (afeta TODAS as rotas seguintes)
209
- export const myRoutes = new Elysia()
210
- .use(cryptoAuthRequired()) // ❌ ERRADO
211
- .get('/publica', () => {}) // Esta rota ficará protegida!
212
- ```
213
-
214
- ## 📚 Documentação Completa
215
-
216
- - **Guia Detalhado**: `EXEMPLO-ROTA-PROTEGIDA.md`
217
- - **Referência de Middlewares**: `CRYPTO-AUTH-MIDDLEWARE-GUIDE.md`
218
-
219
- ---
220
-
221
- **Pronto!** Agora você pode criar rotas protegidas em minutos. 🚀