@sylix/coworker 2.0.10 → 2.0.12

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 (178) hide show
  1. package/dist/commands/slash/config.d.ts.map +1 -1
  2. package/dist/commands/slash/config.js +23 -5
  3. package/dist/commands/slash/config.js.map +1 -1
  4. package/dist/commands/slash/todo.js +1 -1
  5. package/dist/commands/slash/todo.js.map +1 -1
  6. package/dist/core/CoWorkerAgent.d.ts.map +1 -1
  7. package/dist/core/CoWorkerAgent.js +6 -3
  8. package/dist/core/CoWorkerAgent.js.map +1 -1
  9. package/dist/permissions/PermissionInterceptor.js +1 -1
  10. package/dist/permissions/PermissionInterceptor.js.map +1 -1
  11. package/dist/skills/defaults/accessibility/screen-reader-testing.md +545 -0
  12. package/dist/skills/defaults/accessibility/wcag-audit-patterns.md +555 -0
  13. package/dist/skills/defaults/ai-ml/rag.md +276 -0
  14. package/dist/skills/defaults/backend-development/api-design-principles.md +528 -0
  15. package/dist/skills/defaults/backend-development/api-design.md +285 -0
  16. package/dist/skills/defaults/backend-development/architecture-patterns.md +494 -0
  17. package/dist/skills/defaults/backend-development/async-python.md +237 -0
  18. package/dist/skills/defaults/backend-development/auth-implementation-patterns.md +638 -0
  19. package/dist/skills/defaults/backend-development/bazel-build-optimization.md +387 -0
  20. package/dist/skills/defaults/backend-development/billing-automation/SKILL.md +566 -0
  21. package/dist/skills/defaults/backend-development/code-review-excellence.md +538 -0
  22. package/dist/skills/defaults/backend-development/cqrs-implementation.md +554 -0
  23. package/dist/skills/defaults/backend-development/database-design.md +305 -0
  24. package/dist/skills/defaults/backend-development/debugging-strategies.md +536 -0
  25. package/dist/skills/defaults/backend-development/e2e-testing-patterns.md +544 -0
  26. package/dist/skills/defaults/backend-development/error-handling-patterns.md +641 -0
  27. package/dist/skills/defaults/backend-development/fastapi-templates.md +559 -0
  28. package/dist/skills/defaults/backend-development/fastapi.md +309 -0
  29. package/dist/skills/defaults/backend-development/git-advanced-workflows.md +405 -0
  30. package/dist/skills/defaults/backend-development/microservices-patterns.md +595 -0
  31. package/dist/skills/defaults/backend-development/microservices.md +284 -0
  32. package/dist/skills/defaults/backend-development/monorepo-management.md +623 -0
  33. package/dist/skills/defaults/backend-development/nodejs-backend-patterns.md +1048 -0
  34. package/dist/skills/defaults/backend-development/nx-workspace-patterns.md +457 -0
  35. package/dist/skills/defaults/backend-development/paypal-integration/SKILL.md +478 -0
  36. package/dist/skills/defaults/backend-development/pci-compliance/SKILL.md +480 -0
  37. package/dist/skills/defaults/backend-development/python-anti-patterns.md +349 -0
  38. package/dist/skills/defaults/backend-development/python-background-jobs.md +364 -0
  39. package/dist/skills/defaults/backend-development/python-code-style.md +360 -0
  40. package/dist/skills/defaults/backend-development/python-configuration.md +368 -0
  41. package/dist/skills/defaults/backend-development/python-design-patterns.md +296 -0
  42. package/dist/skills/defaults/backend-development/python-error-handling.md +323 -0
  43. package/dist/skills/defaults/backend-development/python-packaging.md +887 -0
  44. package/dist/skills/defaults/backend-development/python-performance-optimization.md +874 -0
  45. package/dist/skills/defaults/backend-development/python-project-structure.md +252 -0
  46. package/dist/skills/defaults/backend-development/python-resilience.md +376 -0
  47. package/dist/skills/defaults/backend-development/python-resource-management.md +421 -0
  48. package/dist/skills/defaults/backend-development/python-type-safety.md +428 -0
  49. package/dist/skills/defaults/backend-development/sql-optimization-patterns.md +509 -0
  50. package/dist/skills/defaults/backend-development/stripe-integration/SKILL.md +522 -0
  51. package/dist/skills/defaults/backend-development/turborepo-caching.md +376 -0
  52. package/dist/skills/defaults/blockchain/defi-protocol-templates.md +430 -0
  53. package/dist/skills/defaults/blockchain/nft-standards.md +364 -0
  54. package/dist/skills/defaults/blockchain/solidity-security.md +514 -0
  55. package/dist/skills/defaults/blockchain/web3-testing.md +360 -0
  56. package/dist/skills/defaults/business/competitive-landscape/SKILL.md +527 -0
  57. package/dist/skills/defaults/business/market-sizing-analysis/SKILL.md +451 -0
  58. package/dist/skills/defaults/business/startup-financial-modeling/SKILL.md +494 -0
  59. package/dist/skills/defaults/business/startup-metrics-framework/SKILL.md +564 -0
  60. package/dist/skills/defaults/business/team-composition-analysis.md +437 -0
  61. package/dist/skills/defaults/compliance/employment-contract-templates/SKILL.md +527 -0
  62. package/dist/skills/defaults/compliance/gdpr-data-handling/SKILL.md +630 -0
  63. package/dist/skills/defaults/data-engineering/airflow-dag-patterns.md +436 -0
  64. package/dist/skills/defaults/data-engineering/airflow.md +519 -0
  65. package/dist/skills/defaults/data-engineering/data-quality.md +583 -0
  66. package/dist/skills/defaults/data-engineering/dbt-transformation-patterns.md +482 -0
  67. package/dist/skills/defaults/data-engineering/dbt.md +556 -0
  68. package/dist/skills/defaults/data-engineering/ml-pipeline-workflow/SKILL.md +247 -0
  69. package/dist/skills/defaults/data-engineering/spark-optimization.md +348 -0
  70. package/dist/skills/defaults/data-engineering/spark.md +411 -0
  71. package/dist/skills/defaults/database/postgresql.md +202 -0
  72. package/dist/skills/defaults/debugging/systematic-debugging.md +249 -0
  73. package/dist/skills/defaults/devops/architecture-decision-records.md +448 -0
  74. package/dist/skills/defaults/devops/changelog-automation.md +580 -0
  75. package/dist/skills/defaults/devops/cicd.md +314 -0
  76. package/dist/skills/defaults/devops/cloud.md +263 -0
  77. package/dist/skills/defaults/devops/code-review-excellence.md +299 -0
  78. package/dist/skills/defaults/devops/cost-optimization.md +295 -0
  79. package/dist/skills/defaults/devops/deployment-pipeline-design.md +356 -0
  80. package/dist/skills/defaults/devops/docker.md +281 -0
  81. package/dist/skills/defaults/devops/git-workflows.md +205 -0
  82. package/dist/skills/defaults/devops/github-actions.md +311 -0
  83. package/dist/skills/defaults/devops/gitlab-ci-patterns.md +266 -0
  84. package/dist/skills/defaults/devops/hybrid-cloud-networking.md +241 -0
  85. package/dist/skills/defaults/devops/istio-traffic-management.md +327 -0
  86. package/dist/skills/defaults/devops/kubernetes.md +339 -0
  87. package/dist/skills/defaults/devops/linkerd-patterns.md +311 -0
  88. package/dist/skills/defaults/devops/multi-cloud-architecture.md +181 -0
  89. package/dist/skills/defaults/devops/observability.md +243 -0
  90. package/dist/skills/defaults/devops/openapi-spec-generation.md +1024 -0
  91. package/dist/skills/defaults/devops/postmortem-writing.md +396 -0
  92. package/dist/skills/defaults/devops/prometheus-configuration.md +265 -0
  93. package/dist/skills/defaults/devops/secrets-management.md +341 -0
  94. package/dist/skills/defaults/devops/service-mesh-observability.md +385 -0
  95. package/dist/skills/defaults/devops/terraform-module-library.md +244 -0
  96. package/dist/skills/defaults/finance/backtesting-frameworks/SKILL.md +663 -0
  97. package/dist/skills/defaults/finance/risk-metrics-calculation/SKILL.md +557 -0
  98. package/dist/skills/defaults/frontend/accessibility-compliance.md +420 -0
  99. package/dist/skills/defaults/frontend/design-system-patterns.md +337 -0
  100. package/dist/skills/defaults/frontend/interaction-design.md +327 -0
  101. package/dist/skills/defaults/frontend/javascript.md +311 -0
  102. package/dist/skills/defaults/frontend/modern-javascript-patterns.md +927 -0
  103. package/dist/skills/defaults/frontend/react-native-design.md +440 -0
  104. package/dist/skills/defaults/frontend/react.md +345 -0
  105. package/dist/skills/defaults/frontend/responsive-design.md +472 -0
  106. package/dist/skills/defaults/frontend/tailwind-design-system.md +337 -0
  107. package/dist/skills/defaults/frontend/typescript-advanced-types.md +724 -0
  108. package/dist/skills/defaults/frontend/typescript.md +334 -0
  109. package/dist/skills/defaults/frontend/visual-design-foundations.md +326 -0
  110. package/dist/skills/defaults/frontend/web-component-design.md +279 -0
  111. package/dist/skills/defaults/game-development/godot-gdscript-patterns.md +188 -0
  112. package/dist/skills/defaults/game-development/unity-ecs-patterns.md +594 -0
  113. package/dist/skills/defaults/kubernetes/gitops-workflow.md +285 -0
  114. package/dist/skills/defaults/kubernetes/gitops.md +280 -0
  115. package/dist/skills/defaults/kubernetes/helm-chart-scaffolding.md +553 -0
  116. package/dist/skills/defaults/kubernetes/helm.md +343 -0
  117. package/dist/skills/defaults/kubernetes/k8s-manifest-generator.md +501 -0
  118. package/dist/skills/defaults/kubernetes/k8s-security-policies.md +342 -0
  119. package/dist/skills/defaults/kubernetes/manifests.md +330 -0
  120. package/dist/skills/defaults/kubernetes/security.md +337 -0
  121. package/dist/skills/defaults/llm-application/embedding-strategies.md +608 -0
  122. package/dist/skills/defaults/llm-application/hybrid-search-implementation.md +570 -0
  123. package/dist/skills/defaults/llm-application/hybrid-search.md +570 -0
  124. package/dist/skills/defaults/llm-application/langchain-architecture.md +666 -0
  125. package/dist/skills/defaults/llm-application/langchain.md +259 -0
  126. package/dist/skills/defaults/llm-application/llm-evaluation.md +695 -0
  127. package/dist/skills/defaults/llm-application/prompt-engineering-patterns.md +449 -0
  128. package/dist/skills/defaults/llm-application/prompt-engineering.md +219 -0
  129. package/dist/skills/defaults/llm-application/rag-implementation.md +434 -0
  130. package/dist/skills/defaults/llm-application/similarity-search-patterns.md +560 -0
  131. package/dist/skills/defaults/llm-application/similarity-search.md +560 -0
  132. package/dist/skills/defaults/llm-application/vector-index-tuning.md +523 -0
  133. package/dist/skills/defaults/mobile/mobile-android-design.md +440 -0
  134. package/dist/skills/defaults/mobile/mobile-ios-design.md +266 -0
  135. package/dist/skills/defaults/monitoring/distributed-tracing.md +436 -0
  136. package/dist/skills/defaults/monitoring/grafana-dashboards.md +370 -0
  137. package/dist/skills/defaults/monitoring/prometheus-configuration.md +379 -0
  138. package/dist/skills/defaults/monitoring/slo-implementation.md +323 -0
  139. package/dist/skills/defaults/refactoring/code-refactoring.md +349 -0
  140. package/dist/skills/defaults/security/anti-reversing-techniques/SKILL.md +559 -0
  141. package/dist/skills/defaults/security/auditor.md +168 -0
  142. package/dist/skills/defaults/security/binary-analysis-patterns/SKILL.md +438 -0
  143. package/dist/skills/defaults/security/memory-forensics/SKILL.md +483 -0
  144. package/dist/skills/defaults/security/mtls-configuration.md +349 -0
  145. package/dist/skills/defaults/security/protocol-reverse-engineering/SKILL.md +520 -0
  146. package/dist/skills/defaults/security/sast-configuration.md +182 -0
  147. package/dist/skills/defaults/security/security.md +313 -0
  148. package/dist/skills/defaults/security/stride-analysis.md +273 -0
  149. package/dist/skills/defaults/security/threat-mitigation-mapping.md +290 -0
  150. package/dist/skills/defaults/systems/bash-defensive-patterns/SKILL.md +539 -0
  151. package/dist/skills/defaults/systems/bats-testing-patterns/SKILL.md +631 -0
  152. package/dist/skills/defaults/systems/go-concurrency-patterns.md +657 -0
  153. package/dist/skills/defaults/systems/memory-safety-patterns.md +605 -0
  154. package/dist/skills/defaults/systems/rust-async-patterns.md +519 -0
  155. package/dist/skills/defaults/systems/shellcheck-configuration/SKILL.md +456 -0
  156. package/dist/skills/defaults/team-collaboration/multi-reviewer-patterns.md +126 -0
  157. package/dist/skills/defaults/team-collaboration/parallel-feature-development.md +151 -0
  158. package/dist/skills/defaults/testing/javascript-testing-patterns.md +1021 -0
  159. package/dist/skills/defaults/testing/python-testing-patterns.md +351 -0
  160. package/dist/skills/defaults/testing/testing.md +332 -0
  161. package/dist/skills/defaults/workflows/context-driven-development.md +384 -0
  162. package/dist/skills/defaults/workflows/track-management.md +592 -0
  163. package/dist/skills/defaults/workflows/workflow-patterns.md +622 -0
  164. package/dist/skills/index.d.ts +11 -0
  165. package/dist/skills/index.d.ts.map +1 -0
  166. package/dist/skills/index.js +129 -0
  167. package/dist/skills/index.js.map +1 -0
  168. package/dist/utils/character.js +6 -9
  169. package/dist/utils/character.js.map +1 -1
  170. package/dist/utils/contextManager.js +3 -7
  171. package/dist/utils/contextManager.js.map +1 -1
  172. package/dist/utils/inputbar.d.ts.map +1 -1
  173. package/dist/utils/inputbar.js +8 -1
  174. package/dist/utils/inputbar.js.map +1 -1
  175. package/dist/utils/output.d.ts.map +1 -1
  176. package/dist/utils/output.js +3 -35
  177. package/dist/utils/output.js.map +1 -1
  178. package/package.json +1 -1
@@ -0,0 +1,638 @@
1
+ ---
2
+ name: auth-implementation-patterns
3
+ description: Master authentication and authorization patterns including JWT, OAuth2, session management, and RBAC to build secure, scalable access control systems. Use when implementing auth systems, securing APIs, or debugging security issues.
4
+ ---
5
+
6
+ # Authentication & Authorization Implementation Patterns
7
+
8
+ Build secure, scalable authentication and authorization systems using industry-standard patterns and modern best practices.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Implementing user authentication systems
13
+ - Securing REST or GraphQL APIs
14
+ - Adding OAuth2/social login
15
+ - Implementing role-based access control (RBAC)
16
+ - Designing session management
17
+ - Migrating authentication systems
18
+ - Debugging auth issues
19
+ - Implementing SSO or multi-tenancy
20
+
21
+ ## Core Concepts
22
+
23
+ ### 1. Authentication vs Authorization
24
+
25
+ **Authentication (AuthN)**: Who are you?
26
+
27
+ - Verifying identity (username/password, OAuth, biometrics)
28
+ - Issuing credentials (sessions, tokens)
29
+ - Managing login/logout
30
+
31
+ **Authorization (AuthZ)**: What can you do?
32
+
33
+ - Permission checking
34
+ - Role-based access control (RBAC)
35
+ - Resource ownership validation
36
+ - Policy enforcement
37
+
38
+ ### 2. Authentication Strategies
39
+
40
+ **Session-Based:**
41
+
42
+ - Server stores session state
43
+ - Session ID in cookie
44
+ - Traditional, simple, stateful
45
+
46
+ **Token-Based (JWT):**
47
+
48
+ - Stateless, self-contained
49
+ - Scales horizontally
50
+ - Can store claims
51
+
52
+ **OAuth2/OpenID Connect:**
53
+
54
+ - Delegate authentication
55
+ - Social login (Google, GitHub)
56
+ - Enterprise SSO
57
+
58
+ ## JWT Authentication
59
+
60
+ ### Pattern 1: JWT Implementation
61
+
62
+ ```typescript
63
+ // JWT structure: header.payload.signature
64
+ import jwt from "jsonwebtoken";
65
+ import { Request, Response, NextFunction } from "express";
66
+
67
+ interface JWTPayload {
68
+ userId: string;
69
+ email: string;
70
+ role: string;
71
+ iat: number;
72
+ exp: number;
73
+ }
74
+
75
+ // Generate JWT
76
+ function generateTokens(userId: string, email: string, role: string) {
77
+ const accessToken = jwt.sign(
78
+ { userId, email, role },
79
+ process.env.JWT_SECRET!,
80
+ { expiresIn: "15m" }, // Short-lived
81
+ );
82
+
83
+ const refreshToken = jwt.sign(
84
+ { userId },
85
+ process.env.JWT_REFRESH_SECRET!,
86
+ { expiresIn: "7d" }, // Long-lived
87
+ );
88
+
89
+ return { accessToken, refreshToken };
90
+ }
91
+
92
+ // Verify JWT
93
+ function verifyToken(token: string): JWTPayload {
94
+ try {
95
+ return jwt.verify(token, process.env.JWT_SECRET!) as JWTPayload;
96
+ } catch (error) {
97
+ if (error instanceof jwt.TokenExpiredError) {
98
+ throw new Error("Token expired");
99
+ }
100
+ if (error instanceof jwt.JsonWebTokenError) {
101
+ throw new Error("Invalid token");
102
+ }
103
+ throw error;
104
+ }
105
+ }
106
+
107
+ // Middleware
108
+ function authenticate(req: Request, res: Response, next: NextFunction) {
109
+ const authHeader = req.headers.authorization;
110
+ if (!authHeader?.startsWith("Bearer ")) {
111
+ return res.status(401).json({ error: "No token provided" });
112
+ }
113
+
114
+ const token = authHeader.substring(7);
115
+ try {
116
+ const payload = verifyToken(token);
117
+ req.user = payload; // Attach user to request
118
+ next();
119
+ } catch (error) {
120
+ return res.status(401).json({ error: "Invalid token" });
121
+ }
122
+ }
123
+
124
+ // Usage
125
+ app.get("/api/profile", authenticate, (req, res) => {
126
+ res.json({ user: req.user });
127
+ });
128
+ ```
129
+
130
+ ### Pattern 2: Refresh Token Flow
131
+
132
+ ```typescript
133
+ interface StoredRefreshToken {
134
+ token: string;
135
+ userId: string;
136
+ expiresAt: Date;
137
+ createdAt: Date;
138
+ }
139
+
140
+ class RefreshTokenService {
141
+ // Store refresh token in database
142
+ async storeRefreshToken(userId: string, refreshToken: string) {
143
+ const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
144
+ await db.refreshTokens.create({
145
+ token: await hash(refreshToken), // Hash before storing
146
+ userId,
147
+ expiresAt,
148
+ });
149
+ }
150
+
151
+ // Refresh access token
152
+ async refreshAccessToken(refreshToken: string) {
153
+ // Verify refresh token
154
+ let payload;
155
+ try {
156
+ payload = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET!) as {
157
+ userId: string;
158
+ };
159
+ } catch {
160
+ throw new Error("Invalid refresh token");
161
+ }
162
+
163
+ // Check if token exists in database
164
+ const storedToken = await db.refreshTokens.findOne({
165
+ where: {
166
+ token: await hash(refreshToken),
167
+ userId: payload.userId,
168
+ expiresAt: { $gt: new Date() },
169
+ },
170
+ });
171
+
172
+ if (!storedToken) {
173
+ throw new Error("Refresh token not found or expired");
174
+ }
175
+
176
+ // Get user
177
+ const user = await db.users.findById(payload.userId);
178
+ if (!user) {
179
+ throw new Error("User not found");
180
+ }
181
+
182
+ // Generate new access token
183
+ const accessToken = jwt.sign(
184
+ { userId: user.id, email: user.email, role: user.role },
185
+ process.env.JWT_SECRET!,
186
+ { expiresIn: "15m" },
187
+ );
188
+
189
+ return { accessToken };
190
+ }
191
+
192
+ // Revoke refresh token (logout)
193
+ async revokeRefreshToken(refreshToken: string) {
194
+ await db.refreshTokens.deleteOne({
195
+ token: await hash(refreshToken),
196
+ });
197
+ }
198
+
199
+ // Revoke all user tokens (logout all devices)
200
+ async revokeAllUserTokens(userId: string) {
201
+ await db.refreshTokens.deleteMany({ userId });
202
+ }
203
+ }
204
+
205
+ // API endpoints
206
+ app.post("/api/auth/refresh", async (req, res) => {
207
+ const { refreshToken } = req.body;
208
+ try {
209
+ const { accessToken } =
210
+ await refreshTokenService.refreshAccessToken(refreshToken);
211
+ res.json({ accessToken });
212
+ } catch (error) {
213
+ res.status(401).json({ error: "Invalid refresh token" });
214
+ }
215
+ });
216
+
217
+ app.post("/api/auth/logout", authenticate, async (req, res) => {
218
+ const { refreshToken } = req.body;
219
+ await refreshTokenService.revokeRefreshToken(refreshToken);
220
+ res.json({ message: "Logged out successfully" });
221
+ });
222
+ ```
223
+
224
+ ## Session-Based Authentication
225
+
226
+ ### Pattern 1: Express Session
227
+
228
+ ```typescript
229
+ import session from "express-session";
230
+ import RedisStore from "connect-redis";
231
+ import { createClient } from "redis";
232
+
233
+ // Setup Redis for session storage
234
+ const redisClient = createClient({
235
+ url: process.env.REDIS_URL,
236
+ });
237
+ await redisClient.connect();
238
+
239
+ app.use(
240
+ session({
241
+ store: new RedisStore({ client: redisClient }),
242
+ secret: process.env.SESSION_SECRET!,
243
+ resave: false,
244
+ saveUninitialized: false,
245
+ cookie: {
246
+ secure: process.env.NODE_ENV === "production", // HTTPS only
247
+ httpOnly: true, // No JavaScript access
248
+ maxAge: 24 * 60 * 60 * 1000, // 24 hours
249
+ sameSite: "strict", // CSRF protection
250
+ },
251
+ }),
252
+ );
253
+
254
+ // Login
255
+ app.post("/api/auth/login", async (req, res) => {
256
+ const { email, password } = req.body;
257
+
258
+ const user = await db.users.findOne({ email });
259
+ if (!user || !(await verifyPassword(password, user.passwordHash))) {
260
+ return res.status(401).json({ error: "Invalid credentials" });
261
+ }
262
+
263
+ // Store user in session
264
+ req.session.userId = user.id;
265
+ req.session.role = user.role;
266
+
267
+ res.json({ user: { id: user.id, email: user.email, role: user.role } });
268
+ });
269
+
270
+ // Session middleware
271
+ function requireAuth(req: Request, res: Response, next: NextFunction) {
272
+ if (!req.session.userId) {
273
+ return res.status(401).json({ error: "Not authenticated" });
274
+ }
275
+ next();
276
+ }
277
+
278
+ // Protected route
279
+ app.get("/api/profile", requireAuth, async (req, res) => {
280
+ const user = await db.users.findById(req.session.userId);
281
+ res.json({ user });
282
+ });
283
+
284
+ // Logout
285
+ app.post("/api/auth/logout", (req, res) => {
286
+ req.session.destroy((err) => {
287
+ if (err) {
288
+ return res.status(500).json({ error: "Logout failed" });
289
+ }
290
+ res.clearCookie("connect.sid");
291
+ res.json({ message: "Logged out successfully" });
292
+ });
293
+ });
294
+ ```
295
+
296
+ ## OAuth2 / Social Login
297
+
298
+ ### Pattern 1: OAuth2 with Passport.js
299
+
300
+ ```typescript
301
+ import passport from "passport";
302
+ import { Strategy as GoogleStrategy } from "passport-google-oauth20";
303
+ import { Strategy as GitHubStrategy } from "passport-github2";
304
+
305
+ // Google OAuth
306
+ passport.use(
307
+ new GoogleStrategy(
308
+ {
309
+ clientID: process.env.GOOGLE_CLIENT_ID!,
310
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
311
+ callbackURL: "/api/auth/google/callback",
312
+ },
313
+ async (accessToken, refreshToken, profile, done) => {
314
+ try {
315
+ // Find or create user
316
+ let user = await db.users.findOne({
317
+ googleId: profile.id,
318
+ });
319
+
320
+ if (!user) {
321
+ user = await db.users.create({
322
+ googleId: profile.id,
323
+ email: profile.emails?.[0]?.value,
324
+ name: profile.displayName,
325
+ avatar: profile.photos?.[0]?.value,
326
+ });
327
+ }
328
+
329
+ return done(null, user);
330
+ } catch (error) {
331
+ return done(error, undefined);
332
+ }
333
+ },
334
+ ),
335
+ );
336
+
337
+ // Routes
338
+ app.get(
339
+ "/api/auth/google",
340
+ passport.authenticate("google", {
341
+ scope: ["profile", "email"],
342
+ }),
343
+ );
344
+
345
+ app.get(
346
+ "/api/auth/google/callback",
347
+ passport.authenticate("google", { session: false }),
348
+ (req, res) => {
349
+ // Generate JWT
350
+ const tokens = generateTokens(req.user.id, req.user.email, req.user.role);
351
+ // Redirect to frontend with token
352
+ res.redirect(
353
+ `${process.env.FRONTEND_URL}/auth/callback?token=${tokens.accessToken}`,
354
+ );
355
+ },
356
+ );
357
+ ```
358
+
359
+ ## Authorization Patterns
360
+
361
+ ### Pattern 1: Role-Based Access Control (RBAC)
362
+
363
+ ```typescript
364
+ enum Role {
365
+ USER = "user",
366
+ MODERATOR = "moderator",
367
+ ADMIN = "admin",
368
+ }
369
+
370
+ const roleHierarchy: Record<Role, Role[]> = {
371
+ [Role.ADMIN]: [Role.ADMIN, Role.MODERATOR, Role.USER],
372
+ [Role.MODERATOR]: [Role.MODERATOR, Role.USER],
373
+ [Role.USER]: [Role.USER],
374
+ };
375
+
376
+ function hasRole(userRole: Role, requiredRole: Role): boolean {
377
+ return roleHierarchy[userRole].includes(requiredRole);
378
+ }
379
+
380
+ // Middleware
381
+ function requireRole(...roles: Role[]) {
382
+ return (req: Request, res: Response, next: NextFunction) => {
383
+ if (!req.user) {
384
+ return res.status(401).json({ error: "Not authenticated" });
385
+ }
386
+
387
+ if (!roles.some((role) => hasRole(req.user.role, role))) {
388
+ return res.status(403).json({ error: "Insufficient permissions" });
389
+ }
390
+
391
+ next();
392
+ };
393
+ }
394
+
395
+ // Usage
396
+ app.delete(
397
+ "/api/users/:id",
398
+ authenticate,
399
+ requireRole(Role.ADMIN),
400
+ async (req, res) => {
401
+ // Only admins can delete users
402
+ await db.users.delete(req.params.id);
403
+ res.json({ message: "User deleted" });
404
+ },
405
+ );
406
+ ```
407
+
408
+ ### Pattern 2: Permission-Based Access Control
409
+
410
+ ```typescript
411
+ enum Permission {
412
+ READ_USERS = "read:users",
413
+ WRITE_USERS = "write:users",
414
+ DELETE_USERS = "delete:users",
415
+ READ_POSTS = "read:posts",
416
+ WRITE_POSTS = "write:posts",
417
+ }
418
+
419
+ const rolePermissions: Record<Role, Permission[]> = {
420
+ [Role.USER]: [Permission.READ_POSTS, Permission.WRITE_POSTS],
421
+ [Role.MODERATOR]: [
422
+ Permission.READ_POSTS,
423
+ Permission.WRITE_POSTS,
424
+ Permission.READ_USERS,
425
+ ],
426
+ [Role.ADMIN]: Object.values(Permission),
427
+ };
428
+
429
+ function hasPermission(userRole: Role, permission: Permission): boolean {
430
+ return rolePermissions[userRole]?.includes(permission) ?? false;
431
+ }
432
+
433
+ function requirePermission(...permissions: Permission[]) {
434
+ return (req: Request, res: Response, next: NextFunction) => {
435
+ if (!req.user) {
436
+ return res.status(401).json({ error: "Not authenticated" });
437
+ }
438
+
439
+ const hasAllPermissions = permissions.every((permission) =>
440
+ hasPermission(req.user.role, permission),
441
+ );
442
+
443
+ if (!hasAllPermissions) {
444
+ return res.status(403).json({ error: "Insufficient permissions" });
445
+ }
446
+
447
+ next();
448
+ };
449
+ }
450
+
451
+ // Usage
452
+ app.get(
453
+ "/api/users",
454
+ authenticate,
455
+ requirePermission(Permission.READ_USERS),
456
+ async (req, res) => {
457
+ const users = await db.users.findAll();
458
+ res.json({ users });
459
+ },
460
+ );
461
+ ```
462
+
463
+ ### Pattern 3: Resource Ownership
464
+
465
+ ```typescript
466
+ // Check if user owns resource
467
+ async function requireOwnership(
468
+ resourceType: "post" | "comment",
469
+ resourceIdParam: string = "id",
470
+ ) {
471
+ return async (req: Request, res: Response, next: NextFunction) => {
472
+ if (!req.user) {
473
+ return res.status(401).json({ error: "Not authenticated" });
474
+ }
475
+
476
+ const resourceId = req.params[resourceIdParam];
477
+
478
+ // Admins can access anything
479
+ if (req.user.role === Role.ADMIN) {
480
+ return next();
481
+ }
482
+
483
+ // Check ownership
484
+ let resource;
485
+ if (resourceType === "post") {
486
+ resource = await db.posts.findById(resourceId);
487
+ } else if (resourceType === "comment") {
488
+ resource = await db.comments.findById(resourceId);
489
+ }
490
+
491
+ if (!resource) {
492
+ return res.status(404).json({ error: "Resource not found" });
493
+ }
494
+
495
+ if (resource.userId !== req.user.userId) {
496
+ return res.status(403).json({ error: "Not authorized" });
497
+ }
498
+
499
+ next();
500
+ };
501
+ }
502
+
503
+ // Usage
504
+ app.put(
505
+ "/api/posts/:id",
506
+ authenticate,
507
+ requireOwnership("post"),
508
+ async (req, res) => {
509
+ // User can only update their own posts
510
+ const post = await db.posts.update(req.params.id, req.body);
511
+ res.json({ post });
512
+ },
513
+ );
514
+ ```
515
+
516
+ ## Security Best Practices
517
+
518
+ ### Pattern 1: Password Security
519
+
520
+ ```typescript
521
+ import bcrypt from "bcrypt";
522
+ import { z } from "zod";
523
+
524
+ // Password validation schema
525
+ const passwordSchema = z
526
+ .string()
527
+ .min(12, "Password must be at least 12 characters")
528
+ .regex(/[A-Z]/, "Password must contain uppercase letter")
529
+ .regex(/[a-z]/, "Password must contain lowercase letter")
530
+ .regex(/[0-9]/, "Password must contain number")
531
+ .regex(/[^A-Za-z0-9]/, "Password must contain special character");
532
+
533
+ // Hash password
534
+ async function hashPassword(password: string): Promise<string> {
535
+ const saltRounds = 12; // 2^12 iterations
536
+ return bcrypt.hash(password, saltRounds);
537
+ }
538
+
539
+ // Verify password
540
+ async function verifyPassword(
541
+ password: string,
542
+ hash: string,
543
+ ): Promise<boolean> {
544
+ return bcrypt.compare(password, hash);
545
+ }
546
+
547
+ // Registration with password validation
548
+ app.post("/api/auth/register", async (req, res) => {
549
+ try {
550
+ const { email, password } = req.body;
551
+
552
+ // Validate password
553
+ passwordSchema.parse(password);
554
+
555
+ // Check if user exists
556
+ const existingUser = await db.users.findOne({ email });
557
+ if (existingUser) {
558
+ return res.status(400).json({ error: "Email already registered" });
559
+ }
560
+
561
+ // Hash password
562
+ const passwordHash = await hashPassword(password);
563
+
564
+ // Create user
565
+ const user = await db.users.create({
566
+ email,
567
+ passwordHash,
568
+ });
569
+
570
+ // Generate tokens
571
+ const tokens = generateTokens(user.id, user.email, user.role);
572
+
573
+ res.status(201).json({
574
+ user: { id: user.id, email: user.email },
575
+ ...tokens,
576
+ });
577
+ } catch (error) {
578
+ if (error instanceof z.ZodError) {
579
+ return res.status(400).json({ error: error.errors[0].message });
580
+ }
581
+ res.status(500).json({ error: "Registration failed" });
582
+ }
583
+ });
584
+ ```
585
+
586
+ ### Pattern 2: Rate Limiting
587
+
588
+ ```typescript
589
+ import rateLimit from "express-rate-limit";
590
+ import RedisStore from "rate-limit-redis";
591
+
592
+ // Login rate limiter
593
+ const loginLimiter = rateLimit({
594
+ store: new RedisStore({ client: redisClient }),
595
+ windowMs: 15 * 60 * 1000, // 15 minutes
596
+ max: 5, // 5 attempts
597
+ message: "Too many login attempts, please try again later",
598
+ standardHeaders: true,
599
+ legacyHeaders: false,
600
+ });
601
+
602
+ // API rate limiter
603
+ const apiLimiter = rateLimit({
604
+ windowMs: 60 * 1000, // 1 minute
605
+ max: 100, // 100 requests per minute
606
+ standardHeaders: true,
607
+ });
608
+
609
+ // Apply to routes
610
+ app.post("/api/auth/login", loginLimiter, async (req, res) => {
611
+ // Login logic
612
+ });
613
+
614
+ app.use("/api/", apiLimiter);
615
+ ```
616
+
617
+ ## Best Practices
618
+
619
+ 1. **Never Store Plain Passwords**: Always hash with bcrypt/argon2
620
+ 2. **Use HTTPS**: Encrypt data in transit
621
+ 3. **Short-Lived Access Tokens**: 15-30 minutes max
622
+ 4. **Secure Cookies**: httpOnly, secure, sameSite flags
623
+ 5. **Validate All Input**: Email format, password strength
624
+ 6. **Rate Limit Auth Endpoints**: Prevent brute force attacks
625
+ 7. **Implement CSRF Protection**: For session-based auth
626
+ 8. **Rotate Secrets Regularly**: JWT secrets, session secrets
627
+ 9. **Log Security Events**: Login attempts, failed auth
628
+ 10. **Use MFA When Possible**: Extra security layer
629
+
630
+ ## Common Pitfalls
631
+
632
+ - **Weak Passwords**: Enforce strong password policies
633
+ - **JWT in localStorage**: Vulnerable to XSS, use httpOnly cookies
634
+ - **No Token Expiration**: Tokens should expire
635
+ - **Client-Side Auth Checks Only**: Always validate server-side
636
+ - **Insecure Password Reset**: Use secure tokens with expiration
637
+ - **No Rate Limiting**: Vulnerable to brute force
638
+ - **Trusting Client Data**: Always validate on server