create-fluxstack 1.4.1 → 1.5.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.
Files changed (51) hide show
  1. package/.env.example +8 -1
  2. package/CRYPTO-AUTH-MIDDLEWARE-GUIDE.md +475 -0
  3. package/CRYPTO-AUTH-MIDDLEWARES.md +473 -0
  4. package/CRYPTO-AUTH-USAGE.md +491 -0
  5. package/EXEMPLO-ROTA-PROTEGIDA.md +347 -0
  6. package/QUICK-START-CRYPTO-AUTH.md +221 -0
  7. package/app/client/src/App.tsx +4 -1
  8. package/app/client/src/pages/CryptoAuthPage.tsx +394 -0
  9. package/app/server/index.ts +4 -0
  10. package/app/server/routes/crypto-auth-demo.routes.ts +167 -0
  11. package/app/server/routes/example-with-crypto-auth.routes.ts +235 -0
  12. package/app/server/routes/exemplo-posts.routes.ts +161 -0
  13. package/app/server/routes/index.ts +5 -1
  14. package/config/index.ts +9 -1
  15. package/core/cli/generators/plugin.ts +324 -34
  16. package/core/cli/generators/template-engine.ts +5 -0
  17. package/core/cli/plugin-discovery.ts +33 -12
  18. package/core/framework/server.ts +10 -0
  19. package/core/plugins/dependency-manager.ts +89 -22
  20. package/core/plugins/index.ts +4 -0
  21. package/core/plugins/manager.ts +3 -2
  22. package/core/plugins/module-resolver.ts +216 -0
  23. package/core/plugins/registry.ts +28 -1
  24. package/core/utils/logger/index.ts +4 -0
  25. package/fluxstack.config.ts +253 -114
  26. package/package.json +117 -117
  27. package/plugins/crypto-auth/README.md +722 -172
  28. package/plugins/crypto-auth/ai-context.md +1282 -0
  29. package/plugins/crypto-auth/cli/make-protected-route.command.ts +383 -0
  30. package/plugins/crypto-auth/client/CryptoAuthClient.ts +136 -159
  31. package/plugins/crypto-auth/client/components/AuthProvider.tsx +35 -94
  32. package/plugins/crypto-auth/client/components/LoginButton.tsx +36 -53
  33. package/plugins/crypto-auth/client/components/ProtectedRoute.tsx +17 -37
  34. package/plugins/crypto-auth/client/components/index.ts +1 -4
  35. package/plugins/crypto-auth/client/index.ts +1 -1
  36. package/plugins/crypto-auth/config/index.ts +34 -0
  37. package/plugins/crypto-auth/index.ts +84 -152
  38. package/plugins/crypto-auth/package.json +65 -64
  39. package/plugins/crypto-auth/server/AuthMiddleware.ts +19 -75
  40. package/plugins/crypto-auth/server/CryptoAuthService.ts +60 -167
  41. package/plugins/crypto-auth/server/index.ts +15 -2
  42. package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +65 -0
  43. package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +26 -0
  44. package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +76 -0
  45. package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +45 -0
  46. package/plugins/crypto-auth/server/middlewares/helpers.ts +140 -0
  47. package/plugins/crypto-auth/server/middlewares/index.ts +22 -0
  48. package/plugins/crypto-auth/server/middlewares.ts +19 -0
  49. package/test-crypto-auth.ts +101 -0
  50. package/plugins/crypto-auth/client/components/SessionInfo.tsx +0 -242
  51. package/plugins/crypto-auth/plugin.json +0 -29
@@ -1,242 +0,0 @@
1
- /**
2
- * Componente de Informações da Sessão
3
- * Exibe informações detalhadas sobre a sessão atual
4
- */
5
-
6
- import React, { useState } from 'react'
7
- import { useAuth } from './AuthProvider'
8
-
9
- export interface SessionInfoProps {
10
- className?: string
11
- showPrivateKey?: boolean
12
- showFullSessionId?: boolean
13
- compact?: boolean
14
- }
15
-
16
- export const SessionInfo: React.FC<SessionInfoProps> = ({
17
- className = '',
18
- showPrivateKey = false,
19
- showFullSessionId = false,
20
- compact = false
21
- }) => {
22
- const { session, isAuthenticated, isAdmin, permissions, isLoading } = useAuth()
23
- const [showDetails, setShowDetails] = useState(!compact)
24
-
25
- if (isLoading) {
26
- return (
27
- <div className={`animate-pulse ${className}`}>
28
- <div className="h-4 bg-gray-200 rounded w-3/4 mb-2"></div>
29
- <div className="h-4 bg-gray-200 rounded w-1/2"></div>
30
- </div>
31
- )
32
- }
33
-
34
- if (!isAuthenticated || !session) {
35
- return (
36
- <div className={`text-gray-500 ${className}`}>
37
- <p>Não autenticado</p>
38
- </div>
39
- )
40
- }
41
-
42
- const formatDate = (date: Date) => {
43
- return new Intl.DateTimeFormat('pt-BR', {
44
- dateStyle: 'short',
45
- timeStyle: 'medium'
46
- }).format(date)
47
- }
48
-
49
- const truncateId = (id: string, length: number = 8) => {
50
- return showFullSessionId ? id : `${id.substring(0, length)}...`
51
- }
52
-
53
- const copyToClipboard = async (text: string) => {
54
- try {
55
- await navigator.clipboard.writeText(text)
56
- // Você pode adicionar um toast/notification aqui
57
- } catch (err) {
58
- console.error('Erro ao copiar para clipboard:', err)
59
- }
60
- }
61
-
62
- if (compact) {
63
- return (
64
- <div className={`flex items-center gap-2 ${className}`}>
65
- <div className="flex items-center gap-2">
66
- <div className="w-2 h-2 bg-green-500 rounded-full"></div>
67
- <span className="text-sm font-medium">
68
- {truncateId(session.sessionId)}
69
- </span>
70
- {isAdmin && (
71
- <span className="px-2 py-0.5 bg-blue-100 text-blue-800 text-xs rounded-full">
72
- Admin
73
- </span>
74
- )}
75
- </div>
76
- <button
77
- onClick={() => setShowDetails(!showDetails)}
78
- className="text-gray-400 hover:text-gray-600 transition-colors"
79
- >
80
- <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
81
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
82
- </svg>
83
- </button>
84
-
85
- {showDetails && (
86
- <div className="absolute z-10 mt-2 p-4 bg-white border border-gray-200 rounded-lg shadow-lg min-w-80">
87
- <SessionDetails
88
- session={session}
89
- isAdmin={isAdmin}
90
- permissions={permissions}
91
- showPrivateKey={showPrivateKey}
92
- showFullSessionId={showFullSessionId}
93
- onCopy={copyToClipboard}
94
- />
95
- </div>
96
- )}
97
- </div>
98
- )
99
- }
100
-
101
- return (
102
- <div className={`bg-white border border-gray-200 rounded-lg p-4 ${className}`}>
103
- <SessionDetails
104
- session={session}
105
- isAdmin={isAdmin}
106
- permissions={permissions}
107
- showPrivateKey={showPrivateKey}
108
- showFullSessionId={showFullSessionId}
109
- onCopy={copyToClipboard}
110
- />
111
- </div>
112
- )
113
- }
114
-
115
- interface SessionDetailsProps {
116
- session: any
117
- isAdmin: boolean
118
- permissions: string[]
119
- showPrivateKey: boolean
120
- showFullSessionId: boolean
121
- onCopy: (text: string) => void
122
- }
123
-
124
- const SessionDetails: React.FC<SessionDetailsProps> = ({
125
- session,
126
- isAdmin,
127
- permissions,
128
- showPrivateKey,
129
- showFullSessionId,
130
- onCopy
131
- }) => {
132
- const formatDate = (date: Date) => {
133
- return new Intl.DateTimeFormat('pt-BR', {
134
- dateStyle: 'short',
135
- timeStyle: 'medium'
136
- }).format(date)
137
- }
138
-
139
- const CopyButton: React.FC<{ text: string }> = ({ text }) => (
140
- <button
141
- onClick={() => onCopy(text)}
142
- className="ml-2 text-gray-400 hover:text-gray-600 transition-colors"
143
- title="Copiar"
144
- >
145
- <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
146
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
147
- </svg>
148
- </button>
149
- )
150
-
151
- return (
152
- <div className="space-y-3">
153
- <div className="flex items-center justify-between">
154
- <h3 className="text-lg font-semibold text-gray-900">Informações da Sessão</h3>
155
- <div className="flex items-center gap-2">
156
- <div className="w-2 h-2 bg-green-500 rounded-full"></div>
157
- <span className="text-sm text-green-600 font-medium">Ativo</span>
158
- </div>
159
- </div>
160
-
161
- <div className="grid grid-cols-1 gap-3 text-sm">
162
- <div>
163
- <label className="block text-gray-600 font-medium mb-1">Session ID</label>
164
- <div className="flex items-center">
165
- <code className="bg-gray-100 px-2 py-1 rounded text-xs font-mono break-all">
166
- {showFullSessionId ? session.sessionId : `${session.sessionId.substring(0, 16)}...`}
167
- </code>
168
- <CopyButton text={session.sessionId} />
169
- </div>
170
- </div>
171
-
172
- <div>
173
- <label className="block text-gray-600 font-medium mb-1">Chave Pública</label>
174
- <div className="flex items-center">
175
- <code className="bg-gray-100 px-2 py-1 rounded text-xs font-mono break-all">
176
- {showFullSessionId ? session.publicKey : `${session.publicKey.substring(0, 16)}...`}
177
- </code>
178
- <CopyButton text={session.publicKey} />
179
- </div>
180
- </div>
181
-
182
- {showPrivateKey && (
183
- <div>
184
- <label className="block text-red-600 font-medium mb-1">
185
- Chave Privada
186
- <span className="text-xs text-red-500 ml-1">(Confidencial)</span>
187
- </label>
188
- <div className="flex items-center">
189
- <code className="bg-red-50 border border-red-200 px-2 py-1 rounded text-xs font-mono break-all">
190
- {session.privateKey.substring(0, 16)}...
191
- </code>
192
- <CopyButton text={session.privateKey} />
193
- </div>
194
- </div>
195
- )}
196
-
197
- <div className="flex gap-4">
198
- <div>
199
- <label className="block text-gray-600 font-medium mb-1">Status</label>
200
- <div className="flex items-center gap-2">
201
- <span className={`px-2 py-1 rounded-full text-xs font-medium ${
202
- isAdmin
203
- ? 'bg-blue-100 text-blue-800'
204
- : 'bg-green-100 text-green-800'
205
- }`}>
206
- {isAdmin ? 'Administrador' : 'Usuário'}
207
- </span>
208
- </div>
209
- </div>
210
-
211
- <div>
212
- <label className="block text-gray-600 font-medium mb-1">Permissões</label>
213
- <div className="flex flex-wrap gap-1">
214
- {permissions.map((permission) => (
215
- <span
216
- key={permission}
217
- className="px-2 py-0.5 bg-gray-100 text-gray-700 text-xs rounded-full"
218
- >
219
- {permission}
220
- </span>
221
- ))}
222
- </div>
223
- </div>
224
- </div>
225
-
226
- <div className="flex gap-4">
227
- <div>
228
- <label className="block text-gray-600 font-medium mb-1">Criado em</label>
229
- <span className="text-gray-800">{formatDate(session.createdAt)}</span>
230
- </div>
231
-
232
- <div>
233
- <label className="block text-gray-600 font-medium mb-1">Último uso</label>
234
- <span className="text-gray-800">{formatDate(session.lastUsed)}</span>
235
- </div>
236
- </div>
237
- </div>
238
- </div>
239
- )
240
- }
241
-
242
- export default SessionInfo
@@ -1,29 +0,0 @@
1
- {
2
- "name": "crypto-auth",
3
- "version": "1.0.0",
4
- "description": "Sistema de autenticação baseado em criptografia Ed25519 para FluxStack",
5
- "author": "FluxStack Team",
6
- "license": "MIT",
7
- "main": "index.ts",
8
- "keywords": ["fluxstack", "plugin", "authentication", "ed25519", "cryptography"],
9
- "fluxstack": {
10
- "plugin": true,
11
- "version": "^1.0.0",
12
- "category": "auth",
13
- "tags": ["authentication", "ed25519", "cryptography", "security"]
14
- },
15
- "dependencies": {
16
- "@noble/curves": "^1.2.0",
17
- "@noble/hashes": "^1.3.2",
18
- "react": ">=16.8.0"
19
- },
20
- "peerDependencies": {
21
- "react": ">=16.8.0"
22
- },
23
- "files": [
24
- "index.ts",
25
- "server/",
26
- "client/",
27
- "README.md"
28
- ]
29
- }