@smicolon/ai-kit 0.3.1 → 0.4.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 (156) hide show
  1. package/README.md +73 -40
  2. package/dist/index.js +260 -126
  3. package/package.json +5 -5
  4. package/.claude-plugin/marketplace.json +0 -373
  5. package/packs/architect/CHANGELOG.md +0 -17
  6. package/packs/architect/README.md +0 -58
  7. package/packs/architect/agents/system-architect.md +0 -768
  8. package/packs/architect/commands/diagram-create.md +0 -300
  9. package/packs/better-auth/.mcp.json +0 -14
  10. package/packs/better-auth/CHANGELOG.md +0 -26
  11. package/packs/better-auth/README.md +0 -125
  12. package/packs/better-auth/agents/auth-architect.md +0 -278
  13. package/packs/better-auth/commands/auth-provider-add.md +0 -265
  14. package/packs/better-auth/commands/auth-setup.md +0 -298
  15. package/packs/better-auth/skills/auth-security/SKILL.md +0 -425
  16. package/packs/better-auth/skills/better-auth-patterns/SKILL.md +0 -455
  17. package/packs/dev-loop/CHANGELOG.md +0 -69
  18. package/packs/dev-loop/README.md +0 -155
  19. package/packs/dev-loop/commands/cancel-dev.md +0 -21
  20. package/packs/dev-loop/commands/dev-loop.md +0 -72
  21. package/packs/dev-loop/commands/dev-plan.md +0 -351
  22. package/packs/dev-loop/hooks/hooks.json +0 -15
  23. package/packs/dev-loop/hooks/stop-hook.sh +0 -178
  24. package/packs/dev-loop/scripts/setup-dev-loop.sh +0 -194
  25. package/packs/dev-loop/skills/tdd-planner/SKILL.md +0 -249
  26. package/packs/dev-loop/skills/tdd-planner/references/framework-patterns.md +0 -874
  27. package/packs/dev-loop/skills/tdd-planner/references/good-example.md +0 -260
  28. package/packs/dev-loop/skills/tdd-planner/references/plan-template.md +0 -275
  29. package/packs/django/CHANGELOG.md +0 -39
  30. package/packs/django/README.md +0 -92
  31. package/packs/django/agents/django-architect.md +0 -182
  32. package/packs/django/agents/django-builder.md +0 -250
  33. package/packs/django/agents/django-feature-based.md +0 -420
  34. package/packs/django/agents/django-reviewer.md +0 -253
  35. package/packs/django/agents/django-tester.md +0 -230
  36. package/packs/django/commands/api-endpoint.md +0 -285
  37. package/packs/django/commands/model-create.md +0 -178
  38. package/packs/django/commands/test-generate.md +0 -325
  39. package/packs/django/rules/migrations.md +0 -138
  40. package/packs/django/rules/models.md +0 -167
  41. package/packs/django/rules/serializers.md +0 -126
  42. package/packs/django/rules/services.md +0 -131
  43. package/packs/django/rules/tests.md +0 -140
  44. package/packs/django/rules/views.md +0 -102
  45. package/packs/django/skills/import-convention-enforcer/SKILL.md +0 -226
  46. package/packs/django/skills/import-convention-enforcer/patterns/django-imports.md +0 -343
  47. package/packs/django/skills/migration-safety-checker/SKILL.md +0 -375
  48. package/packs/django/skills/model-entity-validator/SKILL.md +0 -298
  49. package/packs/django/skills/performance-optimizer/SKILL.md +0 -447
  50. package/packs/django/skills/red-phase-verifier/SKILL.md +0 -180
  51. package/packs/django/skills/security-first-validator/SKILL.md +0 -435
  52. package/packs/django/skills/test-coverage-advisor/SKILL.md +0 -394
  53. package/packs/django/skills/test-validity-checker/SKILL.md +0 -194
  54. package/packs/failure-log/CHANGELOG.md +0 -20
  55. package/packs/failure-log/README.md +0 -168
  56. package/packs/failure-log/commands/failure-add.md +0 -106
  57. package/packs/failure-log/commands/failure-list.md +0 -89
  58. package/packs/failure-log/hooks/hooks.json +0 -16
  59. package/packs/failure-log/hooks/scripts/inject-failures.sh +0 -64
  60. package/packs/failure-log/skills/failure-log-manager/SKILL.md +0 -164
  61. package/packs/flutter/CHANGELOG.md +0 -19
  62. package/packs/flutter/README.md +0 -170
  63. package/packs/flutter/agents/flutter-architect.md +0 -166
  64. package/packs/flutter/agents/flutter-builder.md +0 -303
  65. package/packs/flutter/agents/release-manager.md +0 -355
  66. package/packs/flutter/commands/fastlane-setup.md +0 -188
  67. package/packs/flutter/commands/flutter-build.md +0 -90
  68. package/packs/flutter/commands/flutter-deploy.md +0 -133
  69. package/packs/flutter/commands/flutter-test.md +0 -117
  70. package/packs/flutter/commands/signing-setup.md +0 -209
  71. package/packs/flutter/hooks/hooks.json +0 -17
  72. package/packs/flutter/skills/fastlane-knowledge/SKILL.md +0 -193
  73. package/packs/flutter/skills/flutter-architecture/SKILL.md +0 -127
  74. package/packs/flutter/skills/store-publishing/SKILL.md +0 -163
  75. package/packs/hono/CHANGELOG.md +0 -19
  76. package/packs/hono/README.md +0 -143
  77. package/packs/hono/agents/hono-architect.md +0 -240
  78. package/packs/hono/agents/hono-builder.md +0 -285
  79. package/packs/hono/agents/hono-reviewer.md +0 -279
  80. package/packs/hono/agents/hono-tester.md +0 -346
  81. package/packs/hono/commands/middleware-create.md +0 -223
  82. package/packs/hono/commands/project-init.md +0 -306
  83. package/packs/hono/commands/route-create.md +0 -153
  84. package/packs/hono/commands/rpc-client.md +0 -263
  85. package/packs/hono/hooks/hooks.json +0 -4
  86. package/packs/hono/skills/cloudflare-bindings/SKILL.md +0 -408
  87. package/packs/hono/skills/hono-patterns/SKILL.md +0 -309
  88. package/packs/hono/skills/rpc-typesafe/SKILL.md +0 -388
  89. package/packs/hono/skills/zod-validation/SKILL.md +0 -332
  90. package/packs/nestjs/CHANGELOG.md +0 -29
  91. package/packs/nestjs/README.md +0 -75
  92. package/packs/nestjs/agents/nestjs-architect.md +0 -402
  93. package/packs/nestjs/agents/nestjs-builder.md +0 -301
  94. package/packs/nestjs/agents/nestjs-tester.md +0 -437
  95. package/packs/nestjs/commands/module-create.md +0 -369
  96. package/packs/nestjs/rules/controllers.md +0 -92
  97. package/packs/nestjs/rules/dto.md +0 -124
  98. package/packs/nestjs/rules/entities.md +0 -102
  99. package/packs/nestjs/rules/services.md +0 -106
  100. package/packs/nestjs/skills/barrel-export-manager/SKILL.md +0 -389
  101. package/packs/nestjs/skills/import-convention-enforcer/SKILL.md +0 -365
  102. package/packs/nextjs/CHANGELOG.md +0 -36
  103. package/packs/nextjs/README.md +0 -76
  104. package/packs/nextjs/agents/frontend-tester.md +0 -680
  105. package/packs/nextjs/agents/frontend-visual.md +0 -820
  106. package/packs/nextjs/agents/nextjs-architect.md +0 -331
  107. package/packs/nextjs/agents/nextjs-modular.md +0 -433
  108. package/packs/nextjs/commands/component-create.md +0 -398
  109. package/packs/nextjs/rules/api-routes.md +0 -129
  110. package/packs/nextjs/rules/components.md +0 -106
  111. package/packs/nextjs/rules/hooks.md +0 -132
  112. package/packs/nextjs/skills/accessibility-validator/SKILL.md +0 -445
  113. package/packs/nextjs/skills/import-convention-enforcer/SKILL.md +0 -399
  114. package/packs/nextjs/skills/react-form-validator/SKILL.md +0 -569
  115. package/packs/nuxtjs/CHANGELOG.md +0 -30
  116. package/packs/nuxtjs/README.md +0 -56
  117. package/packs/nuxtjs/agents/frontend-tester.md +0 -680
  118. package/packs/nuxtjs/agents/frontend-visual.md +0 -820
  119. package/packs/nuxtjs/agents/nuxtjs-architect.md +0 -537
  120. package/packs/nuxtjs/commands/component-create.md +0 -223
  121. package/packs/nuxtjs/rules/components.md +0 -101
  122. package/packs/nuxtjs/rules/composables.md +0 -118
  123. package/packs/nuxtjs/rules/server-routes.md +0 -127
  124. package/packs/nuxtjs/skills/accessibility-validator/SKILL.md +0 -183
  125. package/packs/nuxtjs/skills/import-convention-enforcer/SKILL.md +0 -196
  126. package/packs/nuxtjs/skills/veevalidate-form-validator/SKILL.md +0 -190
  127. package/packs/onboard/CHANGELOG.md +0 -22
  128. package/packs/onboard/README.md +0 -103
  129. package/packs/onboard/agents/onboard-guide.md +0 -118
  130. package/packs/onboard/commands/onboard.md +0 -313
  131. package/packs/onboard/skills/onboard-context-provider/SKILL.md +0 -98
  132. package/packs/tanstack-router/CHANGELOG.md +0 -30
  133. package/packs/tanstack-router/README.md +0 -113
  134. package/packs/tanstack-router/agents/tanstack-architect.md +0 -173
  135. package/packs/tanstack-router/agents/tanstack-builder.md +0 -360
  136. package/packs/tanstack-router/agents/tanstack-tester.md +0 -454
  137. package/packs/tanstack-router/commands/form-create.md +0 -313
  138. package/packs/tanstack-router/commands/query-create.md +0 -263
  139. package/packs/tanstack-router/commands/route-create.md +0 -190
  140. package/packs/tanstack-router/commands/table-create.md +0 -413
  141. package/packs/tanstack-router/skills/ai-patterns/SKILL.md +0 -370
  142. package/packs/tanstack-router/skills/db-patterns/SKILL.md +0 -346
  143. package/packs/tanstack-router/skills/devtools-patterns/SKILL.md +0 -415
  144. package/packs/tanstack-router/skills/form-patterns/SKILL.md +0 -425
  145. package/packs/tanstack-router/skills/pacer-patterns/SKILL.md +0 -341
  146. package/packs/tanstack-router/skills/query-patterns/SKILL.md +0 -359
  147. package/packs/tanstack-router/skills/router-patterns/SKILL.md +0 -285
  148. package/packs/tanstack-router/skills/store-patterns/SKILL.md +0 -351
  149. package/packs/tanstack-router/skills/table-patterns/SKILL.md +0 -531
  150. package/packs/tanstack-router/skills/tanstack-conventions/SKILL.md +0 -428
  151. package/packs/tanstack-router/skills/virtual-patterns/SKILL.md +0 -490
  152. package/packs/worktree/CHANGELOG.md +0 -45
  153. package/packs/worktree/README.md +0 -219
  154. package/packs/worktree/commands/wt.md +0 -93
  155. package/packs/worktree/scripts/wt.sh +0 -957
  156. package/packs/worktree/skills/worktree-manager/SKILL.md +0 -113
@@ -1,298 +0,0 @@
1
- ---
2
- name: auth-setup
3
- description: Initialize Better Auth with configuration and optional auth pages
4
- args:
5
- - name: with-pages
6
- description: Include login, register, and forgot-password pages
7
- required: false
8
- - name: providers
9
- description: Comma-separated list of social providers (google,github,discord)
10
- required: false
11
- - name: 2fa
12
- description: Enable two-factor authentication
13
- required: false
14
- - name: passkeys
15
- description: Enable passkey/WebAuthn support
16
- required: false
17
- ---
18
-
19
- # Setup Better Auth
20
-
21
- Initialize Better Auth with full configuration for your React application.
22
-
23
- ## Instructions
24
-
25
- 1. **Install Dependencies**:
26
- ```bash
27
- bun add better-auth
28
- bun add -D @types/better-auth
29
- ```
30
-
31
- 2. **Create Server Configuration** at `src/lib/auth.ts`:
32
- ```typescript
33
- import { betterAuth } from 'better-auth'
34
- import { prismaAdapter } from 'better-auth/adapters/prisma'
35
- import { prisma } from './prisma'
36
-
37
- export const auth = betterAuth({
38
- database: prismaAdapter(prisma, {
39
- provider: 'postgresql', // or 'mysql', 'sqlite'
40
- }),
41
-
42
- emailAndPassword: {
43
- enabled: true,
44
- requireEmailVerification: true,
45
- password: {
46
- minLength: 12,
47
- requireUppercase: true,
48
- requireNumber: true,
49
- },
50
- sendVerificationEmail: async (user, token, url) => {
51
- // TODO: Implement email sending
52
- console.log('Verification URL:', url)
53
- },
54
- sendResetPasswordToken: async (user, token, url) => {
55
- // TODO: Implement email sending
56
- console.log('Reset URL:', url)
57
- },
58
- },
59
-
60
- session: {
61
- expiresIn: 60 * 60 * 24 * 7, // 7 days
62
- updateAge: 60 * 60 * 24, // Extend daily
63
- cookie: {
64
- httpOnly: true,
65
- secure: process.env.NODE_ENV === 'production',
66
- sameSite: 'lax',
67
- },
68
- },
69
-
70
- // Add social providers if requested
71
- socialProviders: {
72
- // Configured based on --providers flag
73
- },
74
-
75
- // Add plugins if requested
76
- plugins: [
77
- // Added based on --2fa and --passkeys flags
78
- ],
79
- })
80
-
81
- export type Auth = typeof auth
82
- ```
83
-
84
- 3. **Create Auth Client** at `src/auth/client.ts`:
85
- ```typescript
86
- import { createAuthClient } from 'better-auth/react'
87
- import type { Auth } from '@/lib/auth'
88
-
89
- export const authClient = createAuthClient<Auth>({
90
- baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3000',
91
- })
92
-
93
- export const {
94
- signIn,
95
- signUp,
96
- signOut,
97
- useSession,
98
- getSession,
99
- resetPassword,
100
- verifyEmail,
101
- } = authClient
102
- ```
103
-
104
- 4. **Create Auth Hooks** at `src/auth/hooks.ts`:
105
- ```typescript
106
- import { useSession, signOut } from './client'
107
- import { useNavigate } from '@tanstack/react-router'
108
- import { useEffect } from 'react'
109
-
110
- export function useAuth() {
111
- const { data: session, isPending, error } = useSession()
112
-
113
- return {
114
- user: session?.user ?? null,
115
- session: session?.session ?? null,
116
- isAuthenticated: !!session?.user,
117
- isLoading: isPending,
118
- error,
119
- }
120
- }
121
-
122
- export function useRequireAuth() {
123
- const auth = useAuth()
124
- const navigate = useNavigate()
125
-
126
- useEffect(() => {
127
- if (!auth.isLoading && !auth.isAuthenticated) {
128
- navigate({ to: '/login' })
129
- }
130
- }, [auth.isLoading, auth.isAuthenticated, navigate])
131
-
132
- return auth
133
- }
134
-
135
- export function useLogout() {
136
- const navigate = useNavigate()
137
-
138
- return async () => {
139
- await signOut()
140
- navigate({ to: '/login' })
141
- }
142
- }
143
- ```
144
-
145
- 5. **Update Root Route** at `src/routes/__root.tsx`:
146
- ```typescript
147
- import { createRootRouteWithContext, Outlet } from '@tanstack/react-router'
148
- import { getSession } from '@/auth/client'
149
- import type { QueryClient } from '@tanstack/react-query'
150
-
151
- interface RouterContext {
152
- queryClient: QueryClient
153
- session: Awaited<ReturnType<typeof getSession>>['data'] | null
154
- }
155
-
156
- export const Route = createRootRouteWithContext<RouterContext>()({
157
- beforeLoad: async () => {
158
- const result = await getSession()
159
- return { session: result?.data ?? null }
160
- },
161
- component: RootComponent,
162
- })
163
-
164
- function RootComponent() {
165
- return (
166
- <>
167
- <Outlet />
168
- </>
169
- )
170
- }
171
- ```
172
-
173
- 6. **Create Protected Route Layout** at `src/routes/_auth.tsx`:
174
- ```typescript
175
- import { createFileRoute, Outlet, redirect } from '@tanstack/react-router'
176
-
177
- export const Route = createFileRoute('/_auth')({
178
- beforeLoad: async ({ context, location }) => {
179
- if (!context.session) {
180
- throw redirect({
181
- to: '/login',
182
- search: { redirect: location.pathname },
183
- })
184
- }
185
- },
186
- component: () => <Outlet />,
187
- })
188
- ```
189
-
190
- 7. **Create Guest Route Layout** at `src/routes/_guest.tsx`:
191
- ```typescript
192
- import { createFileRoute, Outlet, redirect } from '@tanstack/react-router'
193
-
194
- export const Route = createFileRoute('/_guest')({
195
- beforeLoad: async ({ context }) => {
196
- if (context.session) {
197
- throw redirect({ to: '/dashboard' })
198
- }
199
- },
200
- component: () => <Outlet />,
201
- })
202
- ```
203
-
204
- 8. **If --with-pages, Create Auth Pages**:
205
-
206
- `src/routes/_guest.login.tsx`:
207
- ```typescript
208
- import { createFileRoute } from '@tanstack/react-router'
209
- import { LoginForm } from '@/features/auth/components/LoginForm'
210
- import { SocialLoginButtons } from '@/features/auth/components/SocialLoginButtons'
211
-
212
- export const Route = createFileRoute('/_guest/login')({
213
- component: LoginPage,
214
- })
215
-
216
- function LoginPage() {
217
- return (
218
- <div className="min-h-screen flex items-center justify-center">
219
- <div className="w-full max-w-md space-y-8">
220
- <h1 className="text-2xl font-bold text-center">Sign In</h1>
221
- <LoginForm />
222
- <div className="relative">
223
- <div className="absolute inset-0 flex items-center">
224
- <div className="w-full border-t" />
225
- </div>
226
- <div className="relative flex justify-center text-sm">
227
- <span className="bg-white px-2 text-gray-500">Or continue with</span>
228
- </div>
229
- </div>
230
- <SocialLoginButtons />
231
- </div>
232
- </div>
233
- )
234
- }
235
- ```
236
-
237
- `src/routes/_guest.register.tsx`:
238
- ```typescript
239
- import { createFileRoute } from '@tanstack/react-router'
240
- import { RegisterForm } from '@/features/auth/components/RegisterForm'
241
-
242
- export const Route = createFileRoute('/_guest/register')({
243
- component: RegisterPage,
244
- })
245
-
246
- function RegisterPage() {
247
- return (
248
- <div className="min-h-screen flex items-center justify-center">
249
- <div className="w-full max-w-md space-y-8">
250
- <h1 className="text-2xl font-bold text-center">Create Account</h1>
251
- <RegisterForm />
252
- </div>
253
- </div>
254
- )
255
- }
256
- ```
257
-
258
- 9. **Create Auth Components** in `src/features/auth/components/`:
259
-
260
- - `LoginForm.tsx` - Email/password login form
261
- - `RegisterForm.tsx` - Registration form
262
- - `ForgotPasswordForm.tsx` - Password reset request
263
- - `ResetPasswordForm.tsx` - New password form
264
- - `SocialLoginButtons.tsx` - OAuth provider buttons
265
-
266
- 10. **Add Environment Variables** to `.env`:
267
- ```bash
268
- # Better Auth
269
- BETTER_AUTH_SECRET=your-secret-key-min-32-chars
270
-
271
- # Database
272
- DATABASE_URL=postgresql://...
273
-
274
- # Social Providers (if enabled)
275
- GOOGLE_CLIENT_ID=
276
- GOOGLE_CLIENT_SECRET=
277
- GITHUB_CLIENT_ID=
278
- GITHUB_CLIENT_SECRET=
279
- ```
280
-
281
- 11. **Run Database Migrations**:
282
- ```bash
283
- bunx prisma db push
284
- # or
285
- bunx prisma migrate dev
286
- ```
287
-
288
- ## Quality Checklist
289
-
290
- - [ ] Server auth config at `lib/auth.ts`
291
- - [ ] Client at `auth/client.ts` with typed exports
292
- - [ ] Session loaded in `__root.tsx` beforeLoad
293
- - [ ] Protected routes use `_auth.tsx` layout
294
- - [ ] Guest routes use `_guest.tsx` layout
295
- - [ ] Environment variables documented
296
- - [ ] Database adapter configured
297
- - [ ] Email verification enabled
298
- - [ ] Secure session cookies configured
@@ -1,425 +0,0 @@
1
- ---
2
- name: Auth Security Patterns
3
- description: >-
4
- Auto-enforce authentication security best practices. Activates when
5
- implementing password policies, rate limiting, session security, CSRF
6
- protection, or security headers in auth flows.
7
- version: 1.0.0
8
- ---
9
-
10
- # Auth Security Patterns
11
-
12
- This skill enforces authentication security best practices for Better Auth implementations.
13
-
14
- ## Password Security
15
-
16
- ### Strong Password Policy
17
- ```typescript
18
- import { betterAuth } from 'better-auth'
19
-
20
- export const auth = betterAuth({
21
- emailAndPassword: {
22
- enabled: true,
23
- password: {
24
- minLength: 12,
25
- maxLength: 128,
26
- requireLowercase: true,
27
- requireUppercase: true,
28
- requireNumber: true,
29
- requireSpecialChar: true,
30
- // Custom validation
31
- validate: (password) => {
32
- // Check against common passwords
33
- if (commonPasswords.includes(password.toLowerCase())) {
34
- return 'Password is too common'
35
- }
36
- // Check for repeated characters
37
- if (/(.)\1{2,}/.test(password)) {
38
- return 'Password cannot have 3+ repeated characters'
39
- }
40
- return true
41
- },
42
- },
43
- },
44
- })
45
- ```
46
-
47
- ### Password Hashing
48
- ```typescript
49
- // Better Auth uses bcrypt by default with cost factor 10
50
- // For higher security requirements:
51
- export const auth = betterAuth({
52
- advanced: {
53
- password: {
54
- hash: async (password) => {
55
- const salt = await bcrypt.genSalt(12) // Higher cost
56
- return bcrypt.hash(password, salt)
57
- },
58
- verify: async (password, hash) => {
59
- return bcrypt.compare(password, hash)
60
- },
61
- },
62
- },
63
- })
64
- ```
65
-
66
- ## Rate Limiting
67
-
68
- ### Global Rate Limiting
69
- ```typescript
70
- import { rateLimit } from 'better-auth/plugins/rate-limit'
71
-
72
- export const auth = betterAuth({
73
- plugins: [
74
- rateLimit({
75
- window: 60, // 1 minute window
76
- max: 100, // 100 requests per window
77
- keyGenerator: (req) => {
78
- // Rate limit by IP
79
- return req.headers.get('x-forwarded-for') || req.ip
80
- },
81
- }),
82
- ],
83
- })
84
- ```
85
-
86
- ### Endpoint-Specific Limits
87
- ```typescript
88
- rateLimit({
89
- endpoints: {
90
- // Strict limits for auth endpoints
91
- 'sign-in': {
92
- window: 300, // 5 minutes
93
- max: 5, // 5 attempts
94
- },
95
- 'sign-up': {
96
- window: 3600, // 1 hour
97
- max: 3, // 3 registrations
98
- },
99
- 'reset-password': {
100
- window: 3600, // 1 hour
101
- max: 3, // 3 reset requests
102
- },
103
- 'verify-email': {
104
- window: 60, // 1 minute
105
- max: 5, // 5 verification attempts
106
- },
107
- },
108
- })
109
- ```
110
-
111
- ### Progressive Delays
112
- ```typescript
113
- rateLimit({
114
- endpoints: {
115
- 'sign-in': {
116
- window: 300,
117
- max: 5,
118
- // Add delay after failed attempts
119
- onRateLimitExceeded: async (req, res) => {
120
- const attempts = await getFailedAttempts(req.ip)
121
- const delay = Math.min(attempts * 1000, 30000) // Max 30s
122
- await new Promise(resolve => setTimeout(resolve, delay))
123
- },
124
- },
125
- },
126
- })
127
- ```
128
-
129
- ## Session Security
130
-
131
- ### Secure Session Configuration
132
- ```typescript
133
- export const auth = betterAuth({
134
- session: {
135
- expiresIn: 60 * 60 * 24 * 7, // 7 days max
136
- updateAge: 60 * 60 * 24, // Extend daily on activity
137
-
138
- // Cookie settings
139
- cookie: {
140
- name: '__session',
141
- httpOnly: true,
142
- secure: process.env.NODE_ENV === 'production',
143
- sameSite: 'lax',
144
- path: '/',
145
- domain: process.env.COOKIE_DOMAIN,
146
- },
147
-
148
- // Session cache (reduce DB lookups)
149
- cookieCache: {
150
- enabled: true,
151
- maxAge: 60 * 5, // 5 minute cache
152
- },
153
-
154
- // Require fresh session for sensitive ops
155
- freshAge: 60 * 10, // 10 minutes
156
- },
157
- })
158
- ```
159
-
160
- ### Session Invalidation
161
- ```typescript
162
- import { signOut, useSession } from '@/auth/client'
163
-
164
- // Sign out from current device
165
- await signOut()
166
-
167
- // Sign out from all devices
168
- await signOut({ revokeAllSessions: true })
169
-
170
- // Server-side: Invalidate specific session
171
- await auth.api.invalidateSession({ sessionId })
172
-
173
- // Server-side: Invalidate all user sessions
174
- await auth.api.invalidateUserSessions({ userId })
175
- ```
176
-
177
- ### Session Binding
178
- ```typescript
179
- // Bind session to device fingerprint
180
- export const auth = betterAuth({
181
- session: {
182
- // Store device info
183
- onSessionCreated: async (session, user, request) => {
184
- await prisma.session.update({
185
- where: { id: session.id },
186
- data: {
187
- userAgent: request.headers.get('user-agent'),
188
- ipAddress: request.ip,
189
- },
190
- })
191
- },
192
- // Validate on each request
193
- onSessionValidate: async (session, request) => {
194
- const storedIp = session.ipAddress
195
- const currentIp = request.ip
196
-
197
- // Warn on IP change (but don't block for mobile users)
198
- if (storedIp !== currentIp) {
199
- await logSecurityEvent('session_ip_change', {
200
- sessionId: session.id,
201
- oldIp: storedIp,
202
- newIp: currentIp,
203
- })
204
- }
205
-
206
- return true
207
- },
208
- },
209
- })
210
- ```
211
-
212
- ## CSRF Protection
213
-
214
- ### Token-Based CSRF
215
- ```typescript
216
- export const auth = betterAuth({
217
- csrf: {
218
- enabled: true,
219
- // Double submit cookie pattern
220
- cookieName: '__csrf',
221
- headerName: 'x-csrf-token',
222
- // Token rotation
223
- rotateOnAuthentication: true,
224
- },
225
- })
226
-
227
- // Client: Include CSRF token
228
- const csrfToken = getCookie('__csrf')
229
- await fetch('/api/auth/sign-out', {
230
- method: 'POST',
231
- headers: {
232
- 'x-csrf-token': csrfToken,
233
- },
234
- })
235
- ```
236
-
237
- ### SameSite Cookie Protection
238
- ```typescript
239
- session: {
240
- cookie: {
241
- sameSite: 'strict', // Strictest CSRF protection
242
- // Or 'lax' for balance between security and usability
243
- },
244
- }
245
- ```
246
-
247
- ## Security Headers
248
-
249
- ### Recommended Headers
250
- ```typescript
251
- // Middleware or server config
252
- const securityHeaders = {
253
- 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
254
- 'X-Content-Type-Options': 'nosniff',
255
- 'X-Frame-Options': 'DENY',
256
- 'X-XSS-Protection': '1; mode=block',
257
- 'Referrer-Policy': 'strict-origin-when-cross-origin',
258
- 'Content-Security-Policy': [
259
- "default-src 'self'",
260
- "script-src 'self'",
261
- "style-src 'self' 'unsafe-inline'",
262
- "img-src 'self' data: https:",
263
- "font-src 'self'",
264
- "connect-src 'self'",
265
- "frame-ancestors 'none'",
266
- ].join('; '),
267
- }
268
- ```
269
-
270
- ## Account Security
271
-
272
- ### Account Lockout
273
- ```typescript
274
- export const auth = betterAuth({
275
- emailAndPassword: {
276
- lockout: {
277
- enabled: true,
278
- maxAttempts: 5,
279
- lockoutDuration: 15 * 60, // 15 minutes
280
- // Notify user
281
- onLockout: async (user) => {
282
- await sendEmail({
283
- to: user.email,
284
- subject: 'Account Locked',
285
- html: 'Your account has been locked due to multiple failed login attempts.',
286
- })
287
- },
288
- },
289
- },
290
- })
291
- ```
292
-
293
- ### Email Verification
294
- ```typescript
295
- export const auth = betterAuth({
296
- emailAndPassword: {
297
- requireEmailVerification: true,
298
- verificationTokenExpiry: 60 * 60 * 24, // 24 hours
299
- sendVerificationEmail: async (user, token, url) => {
300
- await sendEmail({
301
- to: user.email,
302
- subject: 'Verify your email',
303
- html: `<a href="${url}">Verify email</a>`,
304
- })
305
- },
306
- },
307
- })
308
- ```
309
-
310
- ### Password Reset Security
311
- ```typescript
312
- export const auth = betterAuth({
313
- emailAndPassword: {
314
- resetPasswordTokenExpiry: 60 * 60, // 1 hour
315
- sendResetPasswordToken: async (user, token, url) => {
316
- await sendEmail({
317
- to: user.email,
318
- subject: 'Reset your password',
319
- html: `<a href="${url}">Reset password</a>`,
320
- })
321
-
322
- // Log for security audit
323
- await logSecurityEvent('password_reset_requested', {
324
- userId: user.id,
325
- email: user.email,
326
- })
327
- },
328
- onPasswordReset: async (user) => {
329
- // Invalidate all existing sessions
330
- await auth.api.invalidateUserSessions({ userId: user.id })
331
-
332
- // Notify user
333
- await sendEmail({
334
- to: user.email,
335
- subject: 'Password changed',
336
- html: 'Your password was recently changed.',
337
- })
338
- },
339
- },
340
- })
341
- ```
342
-
343
- ## Security Logging
344
-
345
- ### Audit Trail
346
- ```typescript
347
- export const auth = betterAuth({
348
- advanced: {
349
- hooks: {
350
- onSignIn: async (user, session) => {
351
- await logSecurityEvent('sign_in', {
352
- userId: user.id,
353
- sessionId: session.id,
354
- method: session.method, // 'email', 'google', etc.
355
- })
356
- },
357
- onSignOut: async (user, session) => {
358
- await logSecurityEvent('sign_out', {
359
- userId: user.id,
360
- sessionId: session.id,
361
- })
362
- },
363
- onSignUp: async (user) => {
364
- await logSecurityEvent('sign_up', {
365
- userId: user.id,
366
- email: user.email,
367
- })
368
- },
369
- },
370
- },
371
- })
372
-
373
- async function logSecurityEvent(event: string, data: Record<string, any>) {
374
- await prisma.securityLog.create({
375
- data: {
376
- event,
377
- data,
378
- timestamp: new Date(),
379
- ip: data.ip,
380
- userAgent: data.userAgent,
381
- },
382
- })
383
- }
384
- ```
385
-
386
- ## Security Checklist
387
-
388
- - [ ] Password minimum 12 characters with complexity
389
- - [ ] Rate limiting on all auth endpoints
390
- - [ ] Session cookies are httpOnly and secure
391
- - [ ] CSRF protection enabled
392
- - [ ] Email verification required
393
- - [ ] Account lockout after failed attempts
394
- - [ ] Security headers configured
395
- - [ ] Password changes invalidate sessions
396
- - [ ] Security events logged
397
- - [ ] 2FA available for users
398
-
399
- ## Anti-Patterns
400
-
401
- ```typescript
402
- // ❌ WRONG: Weak password policy
403
- password: { minLength: 6 }
404
-
405
- // ✅ CORRECT: Strong policy
406
- password: { minLength: 12, requireUppercase: true, ... }
407
-
408
- // ❌ WRONG: No rate limiting
409
- emailAndPassword: { enabled: true }
410
-
411
- // ✅ CORRECT: With rate limiting
412
- plugins: [rateLimit({ ... })]
413
-
414
- // ❌ WRONG: Long-lived sessions
415
- session: { expiresIn: 60 * 60 * 24 * 365 } // 1 year
416
-
417
- // ✅ CORRECT: Reasonable expiry
418
- session: { expiresIn: 60 * 60 * 24 * 7 } // 7 days
419
-
420
- // ❌ WRONG: Cookies without flags
421
- cookie: { name: 'session' }
422
-
423
- // ✅ CORRECT: Secure cookie flags
424
- cookie: { httpOnly: true, secure: true, sameSite: 'lax' }
425
- ```