myaidev-method 0.2.8 → 0.2.9

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 (157) hide show
  1. package/.claude/agents/wordpress-admin.md +271 -0
  2. package/.env.example +0 -1
  3. package/PACKAGE_FIXES_SUMMARY.md +319 -0
  4. package/PAYLOADCMS_AUTH_UPDATE.md +248 -0
  5. package/USER_GUIDE.md +260 -0
  6. package/bin/cli.js +36 -0
  7. package/dist/server/.tsbuildinfo +1 -0
  8. package/dist/server/auth/controllers/AuthController.d.ts +34 -0
  9. package/dist/server/auth/controllers/AuthController.d.ts.map +1 -0
  10. package/dist/server/auth/controllers/AuthController.js +43 -0
  11. package/dist/server/auth/controllers/AuthController.js.map +1 -0
  12. package/dist/server/auth/example-usage.d.ts +53 -0
  13. package/dist/server/auth/example-usage.d.ts.map +1 -0
  14. package/dist/server/auth/example-usage.js +129 -0
  15. package/dist/server/auth/example-usage.js.map +1 -0
  16. package/dist/server/auth/index.d.ts +11 -0
  17. package/dist/server/auth/index.d.ts.map +1 -0
  18. package/dist/server/auth/index.js +15 -0
  19. package/dist/server/auth/index.js.map +1 -0
  20. package/dist/server/auth/layers.d.ts +19 -0
  21. package/dist/server/auth/layers.d.ts.map +1 -0
  22. package/dist/server/auth/layers.js +33 -0
  23. package/dist/server/auth/layers.js.map +1 -0
  24. package/dist/server/auth/middleware/authMiddleware.d.ts +24 -0
  25. package/dist/server/auth/middleware/authMiddleware.d.ts.map +1 -0
  26. package/dist/server/auth/middleware/authMiddleware.js +65 -0
  27. package/dist/server/auth/middleware/authMiddleware.js.map +1 -0
  28. package/dist/server/auth/routes/authRoutes.d.ts +11 -0
  29. package/dist/server/auth/routes/authRoutes.d.ts.map +1 -0
  30. package/dist/server/auth/routes/authRoutes.js +213 -0
  31. package/dist/server/auth/routes/authRoutes.js.map +1 -0
  32. package/dist/server/auth/services/AuditLogService.d.ts +21 -0
  33. package/dist/server/auth/services/AuditLogService.d.ts.map +1 -0
  34. package/dist/server/auth/services/AuditLogService.js +28 -0
  35. package/dist/server/auth/services/AuditLogService.js.map +1 -0
  36. package/dist/server/auth/services/AuthService.d.ts +27 -0
  37. package/dist/server/auth/services/AuthService.d.ts.map +1 -0
  38. package/dist/server/auth/services/AuthService.js +246 -0
  39. package/dist/server/auth/services/AuthService.js.map +1 -0
  40. package/dist/server/auth/services/PasswordService.d.ts +12 -0
  41. package/dist/server/auth/services/PasswordService.d.ts.map +1 -0
  42. package/dist/server/auth/services/PasswordService.js +31 -0
  43. package/dist/server/auth/services/PasswordService.js.map +1 -0
  44. package/dist/server/auth/services/SessionRepository.d.ts +24 -0
  45. package/dist/server/auth/services/SessionRepository.d.ts.map +1 -0
  46. package/dist/server/auth/services/SessionRepository.js +101 -0
  47. package/dist/server/auth/services/SessionRepository.js.map +1 -0
  48. package/dist/server/auth/services/TokenService.d.ts +12 -0
  49. package/dist/server/auth/services/TokenService.d.ts.map +1 -0
  50. package/dist/server/auth/services/TokenService.js +86 -0
  51. package/dist/server/auth/services/TokenService.js.map +1 -0
  52. package/dist/server/auth/services/UserRepository.d.ts +23 -0
  53. package/dist/server/auth/services/UserRepository.d.ts.map +1 -0
  54. package/dist/server/auth/services/UserRepository.js +168 -0
  55. package/dist/server/auth/services/UserRepository.js.map +1 -0
  56. package/dist/server/auth/services/example.d.ts +26 -0
  57. package/dist/server/auth/services/example.d.ts.map +1 -0
  58. package/dist/server/auth/services/example.js +221 -0
  59. package/dist/server/auth/services/example.js.map +1 -0
  60. package/dist/server/auth/services/index.d.ts +6 -0
  61. package/dist/server/auth/services/index.d.ts.map +1 -0
  62. package/dist/server/auth/services/index.js +7 -0
  63. package/dist/server/auth/services/index.js.map +1 -0
  64. package/dist/server/database/db.d.ts +28 -0
  65. package/dist/server/database/db.d.ts.map +1 -0
  66. package/dist/server/database/db.js +91 -0
  67. package/dist/server/database/db.js.map +1 -0
  68. package/dist/server/database/schema.sql +95 -0
  69. package/dist/server/hono/app.d.ts +10 -0
  70. package/dist/server/hono/app.d.ts.map +1 -0
  71. package/dist/server/hono/app.js +26 -0
  72. package/dist/server/hono/app.js.map +1 -0
  73. package/dist/server/hono/routes.d.ts +12 -0
  74. package/dist/server/hono/routes.d.ts.map +1 -0
  75. package/dist/server/hono/routes.js +40 -0
  76. package/dist/server/hono/routes.js.map +1 -0
  77. package/dist/server/main.d.ts +2 -0
  78. package/dist/server/main.d.ts.map +1 -0
  79. package/dist/server/main.js +94 -0
  80. package/dist/server/main.js.map +1 -0
  81. package/dist/server/user-management/DirectoryService.d.ts +62 -0
  82. package/dist/server/user-management/DirectoryService.d.ts.map +1 -0
  83. package/dist/server/user-management/DirectoryService.js +201 -0
  84. package/dist/server/user-management/DirectoryService.js.map +1 -0
  85. package/dist/server/user-management/LinuxUserService.d.ts +71 -0
  86. package/dist/server/user-management/LinuxUserService.d.ts.map +1 -0
  87. package/dist/server/user-management/LinuxUserService.js +192 -0
  88. package/dist/server/user-management/LinuxUserService.js.map +1 -0
  89. package/dist/server/user-management/QuotaService.d.ts +59 -0
  90. package/dist/server/user-management/QuotaService.d.ts.map +1 -0
  91. package/dist/server/user-management/QuotaService.js +148 -0
  92. package/dist/server/user-management/QuotaService.js.map +1 -0
  93. package/dist/server/user-management/UserManagementService.d.ts +74 -0
  94. package/dist/server/user-management/UserManagementService.d.ts.map +1 -0
  95. package/dist/server/user-management/UserManagementService.js +122 -0
  96. package/dist/server/user-management/UserManagementService.js.map +1 -0
  97. package/dist/server/user-management/index.d.ts +26 -0
  98. package/dist/server/user-management/index.d.ts.map +1 -0
  99. package/dist/server/user-management/index.js +26 -0
  100. package/dist/server/user-management/index.js.map +1 -0
  101. package/dist/server/user-management/layers.d.ts +27 -0
  102. package/dist/server/user-management/layers.d.ts.map +1 -0
  103. package/dist/server/user-management/layers.js +37 -0
  104. package/dist/server/user-management/layers.js.map +1 -0
  105. package/dist/shared/types.d.ts +94 -0
  106. package/dist/shared/types.d.ts.map +1 -0
  107. package/dist/shared/types.js +32 -0
  108. package/dist/shared/types.js.map +1 -0
  109. package/package.json +25 -5
  110. package/src/lib/payloadcms-utils.js +5 -12
  111. package/src/server/auth/ARCHITECTURE.md +575 -0
  112. package/src/server/auth/IMPLEMENTATION_SUMMARY.md +287 -0
  113. package/src/server/auth/QUICK_START.md +283 -0
  114. package/src/server/auth/README.md +290 -0
  115. package/src/server/auth/controllers/AuthController.ts +129 -0
  116. package/src/server/auth/example-usage.ts +159 -0
  117. package/src/server/auth/index.ts +19 -0
  118. package/src/server/auth/layers.ts +57 -0
  119. package/src/server/auth/middleware/authMiddleware.ts +118 -0
  120. package/src/server/auth/routes/authRoutes.ts +319 -0
  121. package/src/server/auth/services/AuditLogService.ts +81 -0
  122. package/src/server/auth/services/AuthService.ts +408 -0
  123. package/src/server/auth/services/IMPLEMENTATION_SUMMARY.md +404 -0
  124. package/src/server/auth/services/PasswordService.ts +85 -0
  125. package/src/server/auth/services/README.md +361 -0
  126. package/src/server/auth/services/SessionRepository.ts +227 -0
  127. package/src/server/auth/services/TokenService.ts +174 -0
  128. package/src/server/auth/services/UserRepository.ts +318 -0
  129. package/src/server/auth/services/example.ts +346 -0
  130. package/src/server/auth/services/index.ts +6 -0
  131. package/src/server/database/db.ts +161 -0
  132. package/src/server/database/schema.sql +95 -0
  133. package/src/server/hono/app.ts +41 -0
  134. package/src/server/main.ts +115 -0
  135. package/src/server/user-management/DirectoryService.ts +348 -0
  136. package/src/server/user-management/LinuxUserService.ts +338 -0
  137. package/src/server/user-management/QuotaService.ts +256 -0
  138. package/src/server/user-management/README.md +333 -0
  139. package/src/server/user-management/UserManagementService.ts +335 -0
  140. package/src/server/user-management/index.ts +26 -0
  141. package/src/server/user-management/layers.ts +51 -0
  142. package/src/shared/types.ts +111 -0
  143. package/src/templates/claude/agents/payloadcms-publish.md +34 -14
  144. package/src/templates/codex/commands/myai-astro-publish.md +8 -2
  145. package/src/templates/codex/commands/myai-content-writer.md +8 -2
  146. package/src/templates/codex/commands/myai-coolify-deploy.md +8 -2
  147. package/src/templates/codex/commands/myai-dev-architect.md +8 -2
  148. package/src/templates/codex/commands/myai-dev-code.md +8 -2
  149. package/src/templates/codex/commands/myai-dev-docs.md +8 -2
  150. package/src/templates/codex/commands/myai-dev-review.md +8 -2
  151. package/src/templates/codex/commands/myai-dev-test.md +8 -2
  152. package/src/templates/codex/commands/myai-docusaurus-publish.md +8 -2
  153. package/src/templates/codex/commands/myai-mintlify-publish.md +8 -2
  154. package/src/templates/codex/commands/myai-payloadcms-publish.md +17 -3
  155. package/src/templates/codex/commands/myai-sparc-workflow.md +8 -2
  156. package/src/templates/codex/commands/myai-wordpress-admin.md +8 -2
  157. package/src/templates/codex/commands/myai-wordpress-publish.md +8 -2
@@ -0,0 +1,95 @@
1
+ -- Users table
2
+ CREATE TABLE IF NOT EXISTS users (
3
+ id TEXT PRIMARY KEY,
4
+ username TEXT UNIQUE NOT NULL,
5
+ email TEXT UNIQUE NOT NULL,
6
+ password_hash TEXT,
7
+ linux_username TEXT UNIQUE NOT NULL,
8
+ created_at INTEGER DEFAULT (strftime('%s','now')),
9
+ updated_at INTEGER DEFAULT (strftime('%s','now')),
10
+ is_active INTEGER DEFAULT 1,
11
+ email_verified INTEGER DEFAULT 0,
12
+ failed_login_attempts INTEGER DEFAULT 0,
13
+ last_login_at INTEGER,
14
+ CONSTRAINT username_format CHECK (length(username) >= 3 AND length(username) <= 32),
15
+ CONSTRAINT email_format CHECK (email LIKE '%_@__%.__%')
16
+ );
17
+
18
+ -- Index for faster user lookups
19
+ CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
20
+ CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
21
+ CREATE INDEX IF NOT EXISTS idx_users_linux_username ON users(linux_username);
22
+
23
+ -- OAuth2 providers table
24
+ CREATE TABLE IF NOT EXISTS oauth2_providers (
25
+ id TEXT PRIMARY KEY,
26
+ user_id TEXT NOT NULL,
27
+ provider TEXT NOT NULL,
28
+ provider_user_id TEXT NOT NULL,
29
+ provider_email TEXT,
30
+ access_token TEXT,
31
+ refresh_token TEXT,
32
+ token_expires_at INTEGER,
33
+ created_at INTEGER DEFAULT (strftime('%s','now')),
34
+ updated_at INTEGER DEFAULT (strftime('%s','now')),
35
+ UNIQUE(provider, provider_user_id),
36
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
37
+ );
38
+
39
+ -- Index for OAuth lookups
40
+ CREATE INDEX IF NOT EXISTS idx_oauth2_user_id ON oauth2_providers(user_id);
41
+ CREATE INDEX IF NOT EXISTS idx_oauth2_provider_lookup ON oauth2_providers(provider, provider_user_id);
42
+
43
+ -- Sessions table
44
+ CREATE TABLE IF NOT EXISTS sessions (
45
+ id TEXT PRIMARY KEY,
46
+ user_id TEXT NOT NULL,
47
+ token_hash TEXT NOT NULL UNIQUE,
48
+ ip_address TEXT,
49
+ user_agent TEXT,
50
+ created_at INTEGER DEFAULT (strftime('%s','now')),
51
+ expires_at INTEGER NOT NULL,
52
+ is_revoked INTEGER DEFAULT 0,
53
+ revoked_at INTEGER,
54
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
55
+ );
56
+
57
+ -- Index for session lookups
58
+ CREATE INDEX IF NOT EXISTS idx_sessions_token_hash ON sessions(token_hash);
59
+ CREATE INDEX IF NOT EXISTS idx_sessions_user_id ON sessions(user_id);
60
+ CREATE INDEX IF NOT EXISTS idx_sessions_expires_at ON sessions(expires_at);
61
+
62
+ -- Audit log table
63
+ CREATE TABLE IF NOT EXISTS audit_logs (
64
+ id TEXT PRIMARY KEY,
65
+ user_id TEXT,
66
+ action TEXT NOT NULL,
67
+ resource_type TEXT,
68
+ resource_id TEXT,
69
+ ip_address TEXT,
70
+ user_agent TEXT,
71
+ details TEXT,
72
+ created_at INTEGER DEFAULT (strftime('%s','now')),
73
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
74
+ );
75
+
76
+ -- Index for audit log queries
77
+ CREATE INDEX IF NOT EXISTS idx_audit_logs_user_id ON audit_logs(user_id);
78
+ CREATE INDEX IF NOT EXISTS idx_audit_logs_action ON audit_logs(action);
79
+ CREATE INDEX IF NOT EXISTS idx_audit_logs_created_at ON audit_logs(created_at);
80
+
81
+ -- Trigger to update updated_at timestamp for users
82
+ CREATE TRIGGER IF NOT EXISTS update_users_timestamp
83
+ AFTER UPDATE ON users
84
+ FOR EACH ROW
85
+ BEGIN
86
+ UPDATE users SET updated_at = strftime('%s','now') WHERE id = NEW.id;
87
+ END;
88
+
89
+ -- Trigger to update updated_at timestamp for oauth2_providers
90
+ CREATE TRIGGER IF NOT EXISTS update_oauth2_providers_timestamp
91
+ AFTER UPDATE ON oauth2_providers
92
+ FOR EACH ROW
93
+ BEGIN
94
+ UPDATE oauth2_providers SET updated_at = strftime('%s','now') WHERE id = NEW.id;
95
+ END;
@@ -0,0 +1,10 @@
1
+ import { Hono } from "hono";
2
+ import type { User, Session } from "@shared/types.js";
3
+ export type HonoContext = {
4
+ Variables: {
5
+ user?: User;
6
+ session?: Session;
7
+ };
8
+ };
9
+ export declare const createApp: () => Hono<HonoContext, import("hono/types").BlankSchema, "/">;
10
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../src/server/hono/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,EAAE;QACT,IAAI,CAAC,EAAE,IAAI,CAAC;QACZ,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,SAAS,gEA4BrB,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { Hono } from "hono";
2
+ import { cors } from "hono/cors";
3
+ import { logger } from "hono/logger";
4
+ export const createApp = () => {
5
+ const app = new Hono();
6
+ app.use("*", logger());
7
+ app.use("*", cors({
8
+ origin: (origin) => {
9
+ if (process.env["NODE_ENV"] === "development") {
10
+ return origin;
11
+ }
12
+ const allowedOrigins = process.env["ALLOWED_ORIGINS"]?.split(",") ?? [];
13
+ return allowedOrigins.includes(origin) ? origin : allowedOrigins[0];
14
+ },
15
+ credentials: true,
16
+ }));
17
+ app.get("/health", (c) => {
18
+ return c.json({
19
+ status: "healthy",
20
+ timestamp: new Date().toISOString(),
21
+ uptime: process.uptime(),
22
+ });
23
+ });
24
+ return app;
25
+ };
26
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/server/hono/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAUrC,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE;IAC5B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAe,CAAC;IAEpC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IAEvB,GAAG,CAAC,GAAG,CACL,GAAG,EACH,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YACjB,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,aAAa,EAAE,CAAC;gBAC9C,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YACxE,OAAO,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,WAAW,EAAE,IAAI;KAClB,CAAC,CACH,CAAC;IAEF,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QACvB,OAAO,CAAC,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;SACzB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Hono } from "hono";
2
+ import { Effect, Layer } from "effect";
3
+ import type { HonoContext } from "./app.js";
4
+ import { PasswordService } from "../auth/services/PasswordService.js";
5
+ import { TokenService } from "../auth/services/TokenService.js";
6
+ import { UserRepository } from "../auth/services/UserRepository.js";
7
+ import { SessionRepository } from "../auth/services/SessionRepository.js";
8
+ import { AuditLogService } from "../auth/services/AuditLogService.js";
9
+ import { AuthService } from "../auth/services/AuthService.js";
10
+ export declare const AppLayer: Layer.Layer<PasswordService | TokenService | UserRepository | SessionRepository | AuditLogService | AuthService, import("../../shared/types.js").AuthError, PasswordService | TokenService | import("../database/db.js").DatabaseService | UserRepository | SessionRepository | AuditLogService>;
11
+ export declare const setupRoutes: (app: Hono<HonoContext>) => Effect.Effect<void, never>;
12
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/server/hono/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAK9D,eAAO,MAAM,QAAQ,kSAOpB,CAAC;AAGF,eAAO,MAAM,WAAW,GAAI,KAAK,IAAI,CAAC,WAAW,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CA8B1E,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { Effect, Layer } from "effect";
2
+ import { PasswordService } from "../auth/services/PasswordService.js";
3
+ import { TokenService } from "../auth/services/TokenService.js";
4
+ import { UserRepository } from "../auth/services/UserRepository.js";
5
+ import { SessionRepository } from "../auth/services/SessionRepository.js";
6
+ import { AuditLogService } from "../auth/services/AuditLogService.js";
7
+ import { AuthService } from "../auth/services/AuthService.js";
8
+ import authRouter from "../auth/routes/authRoutes.js";
9
+ import authMiddleware from "../auth/middleware/authMiddleware.js";
10
+ // Create the application service layer that requires DatabaseService
11
+ export const AppLayer = Layer.mergeAll(PasswordService.Live, TokenService.Live, AuditLogService.Live).pipe(Layer.provideMerge(Layer.mergeAll(UserRepository.Live, SessionRepository.Live)), Layer.provideMerge(AuthService.Live));
12
+ // Setup routes with Effect-TS dependencies
13
+ export const setupRoutes = (app) => Effect.gen(function* () {
14
+ // Mount auth routes
15
+ app.route("/api/auth", authRouter);
16
+ // Example protected route
17
+ app.get("/api/protected", authMiddleware, (c) => {
18
+ const user = c.get("user");
19
+ const session = c.get("session");
20
+ return c.json({
21
+ message: "This is a protected route",
22
+ user: {
23
+ id: user?.id,
24
+ username: user?.username,
25
+ email: user?.email,
26
+ },
27
+ session: {
28
+ id: session?.id,
29
+ expiresAt: session?.expiresAt,
30
+ },
31
+ });
32
+ });
33
+ console.log("✅ Routes configured successfully");
34
+ console.log(" 📍 POST /api/auth/register - User registration");
35
+ console.log(" 📍 POST /api/auth/login - User login");
36
+ console.log(" 📍 POST /api/auth/logout - User logout (protected)");
37
+ console.log(" 📍 GET /api/auth/me - Current user info (protected)");
38
+ console.log(" 📍 GET /api/protected - Example protected route");
39
+ });
40
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/server/hono/routes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,UAAU,MAAM,8BAA8B,CAAC;AACtD,OAAO,cAAc,MAAM,sCAAsC,CAAC;AAElE,qEAAqE;AACrE,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CACpC,eAAe,CAAC,IAAI,EACpB,YAAY,CAAC,IAAI,EACjB,eAAe,CAAC,IAAI,CACrB,CAAC,IAAI,CACJ,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAC/E,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,CACrC,CAAC;AAEF,2CAA2C;AAC3C,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAsB,EAA8B,EAAE,CAChF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,oBAAoB;IACpB,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAEnC,0BAA0B;IAC1B,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE;QAC9C,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEjC,OAAO,CAAC,CAAC,IAAI,CAAC;YACZ,OAAO,EAAE,2BAA2B;YACpC,IAAI,EAAE;gBACJ,EAAE,EAAE,IAAI,EAAE,EAAE;gBACZ,QAAQ,EAAE,IAAI,EAAE,QAAQ;gBACxB,KAAK,EAAE,IAAI,EAAE,KAAK;aACnB;YACD,OAAO,EAAE;gBACP,EAAE,EAAE,OAAO,EAAE,EAAE;gBACf,SAAS,EAAE,OAAO,EAAE,SAAS;aAC9B;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;AACrE,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/server/main.ts"],"names":[],"mappings":""}
@@ -0,0 +1,94 @@
1
+ import { serve } from "@hono/node-server";
2
+ import { Effect, ManagedRuntime } from "effect";
3
+ import { NodeContext } from "@effect/platform-node";
4
+ import { createApp } from "./hono/app.js";
5
+ import { createAuthRoutes } from "./auth/routes/authRoutes.js";
6
+ import { createAuthMiddleware } from "./auth/middleware/authMiddleware.js";
7
+ import { createAppLayer } from "./auth/layers.js";
8
+ import * as path from "node:path";
9
+ import { homedir } from "node:os";
10
+ const getDefaultDbPath = () => {
11
+ const sqliteDbPath = process.env["SQLITE_DB_PATH"];
12
+ if (sqliteDbPath) {
13
+ return sqliteDbPath;
14
+ }
15
+ if (process.env["SINGLE_USER_MODE"] === "true") {
16
+ const home = homedir();
17
+ return path.join(home, ".myaidev-web", "users.db");
18
+ }
19
+ return path.join(process.cwd(), "data", "users.db");
20
+ };
21
+ // Create the application layer with auth services
22
+ const AppLayer = createAppLayer({
23
+ path: getDefaultDbPath(),
24
+ timeout: 5000,
25
+ verbose: false, // Disable verbose mode to prevent schema logging on every request
26
+ });
27
+ // Build the managed runtime once at startup (memoization with automatic scope management)
28
+ const AppRuntime = ManagedRuntime.make(AppLayer);
29
+ // Create middleware and routes with the memoized runtime
30
+ const authMiddleware = createAuthMiddleware(AppRuntime);
31
+ const authRouter = createAuthRoutes(AppRuntime, authMiddleware);
32
+ const program = Effect.gen(function* () {
33
+ const port = Number.parseInt(process.env["PORT"] ?? "3400", 10);
34
+ const dbPath = getDefaultDbPath();
35
+ console.log(`🔧 Initializing MyAIDev Method Web Server`);
36
+ console.log(`📂 Database path: ${dbPath}`);
37
+ console.log(`🌐 Server port: ${port}`);
38
+ console.log(`✅ Application layer initialized successfully`);
39
+ const app = createApp();
40
+ console.log(`🚀 Starting server on port ${port}...`);
41
+ // Mount authentication routes (already created with AppLayer)
42
+ app.route("/api/auth", authRouter);
43
+ // Example protected route
44
+ app.get("/api/protected", authMiddleware, (c) => {
45
+ const user = c.get("user");
46
+ const session = c.get("session");
47
+ return c.json({
48
+ message: "This is a protected route",
49
+ user: {
50
+ id: user?.id,
51
+ username: user?.username,
52
+ email: user?.email,
53
+ },
54
+ session: {
55
+ id: session?.id,
56
+ expiresAt: session?.expiresAt,
57
+ },
58
+ });
59
+ });
60
+ console.log("✅ Routes configured successfully");
61
+ console.log(" 📍 POST /api/auth/register - User registration");
62
+ console.log(" 📍 POST /api/auth/login - User login");
63
+ console.log(" 📍 POST /api/auth/logout - User logout (protected)");
64
+ console.log(" 📍 GET /api/auth/me - Current user info (protected)");
65
+ console.log(" 📍 GET /api/protected - Example protected route");
66
+ const server = serve({
67
+ fetch: app.fetch,
68
+ port,
69
+ });
70
+ console.log(`✅ Server running at http://localhost:${port}`);
71
+ console.log(`📊 Health check: http://localhost:${port}/health`);
72
+ yield* Effect.async(() => {
73
+ process.on("SIGTERM", () => {
74
+ console.log("\n🛑 SIGTERM received, shutting down gracefully...");
75
+ server.close(() => {
76
+ console.log("✅ Server closed");
77
+ process.exit(0);
78
+ });
79
+ });
80
+ process.on("SIGINT", () => {
81
+ console.log("\n🛑 SIGINT received, shutting down gracefully...");
82
+ server.close(() => {
83
+ console.log("✅ Server closed");
84
+ process.exit(0);
85
+ });
86
+ });
87
+ });
88
+ });
89
+ // Program only needs Node context
90
+ Effect.runPromise(Effect.provide(program, NodeContext.layer)).catch((error) => {
91
+ console.error("❌ Fatal error:", error);
92
+ process.exit(1);
93
+ });
94
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/server/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { Effect, Context, Layer } from "effect";
2
+ /**
3
+ * Directory Management Service
4
+ *
5
+ * Handles creation and management of user home directories,
6
+ * Claude Code configurations, and workspace setup for isolated
7
+ * multi-user environments.
8
+ *
9
+ * Directory Structure:
10
+ * /home/{username}/
11
+ * ├── .claude/ # Claude Code configuration
12
+ * │ ├── config.json # User-specific Claude settings
13
+ * │ ├── sessions/ # Session storage
14
+ * │ └── cache/ # Cache directory
15
+ * ├── workspace/ # User's workspace directory
16
+ * └── .bashrc # Shell configuration
17
+ */
18
+ export interface DirectorySetupOptions {
19
+ username: string;
20
+ homeDir: string;
21
+ uid: number;
22
+ gid: number;
23
+ claudeConfig?: ClaudeConfig;
24
+ }
25
+ export interface ClaudeConfig {
26
+ apiKey?: string;
27
+ model?: string;
28
+ maxTokens?: number;
29
+ temperature?: number;
30
+ }
31
+ export interface DirectoryError {
32
+ readonly _tag: "DirectoryError";
33
+ readonly message: string;
34
+ readonly cause?: unknown;
35
+ }
36
+ declare const DirectoryService_base: Context.TagClass<DirectoryService, "DirectoryService", {
37
+ /**
38
+ * Set up complete home directory structure for a user
39
+ */
40
+ readonly setupHomeDirectory: (options: DirectorySetupOptions) => Effect.Effect<void, DirectoryError>;
41
+ /**
42
+ * Create Claude Code configuration directory
43
+ */
44
+ readonly createClaudeConfig: (homeDir: string, config: ClaudeConfig, uid: number, gid: number) => Effect.Effect<void, DirectoryError>;
45
+ /**
46
+ * Create user workspace directory
47
+ */
48
+ readonly createWorkspace: (homeDir: string, uid: number, gid: number) => Effect.Effect<void, DirectoryError>;
49
+ /**
50
+ * Set proper ownership and permissions
51
+ */
52
+ readonly setOwnership: (dirPath: string, uid: number, gid: number, recursive?: boolean) => Effect.Effect<void, DirectoryError>;
53
+ /**
54
+ * Clean up user directories
55
+ */
56
+ readonly cleanupDirectories: (homeDir: string) => Effect.Effect<void, DirectoryError>;
57
+ }>;
58
+ export declare class DirectoryService extends DirectoryService_base {
59
+ static Live: Layer.Layer<DirectoryService, never, never>;
60
+ }
61
+ export {};
62
+ //# sourceMappingURL=DirectoryService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DirectoryService.d.ts","sourceRoot":"","sources":["../../../src/server/user-management/DirectoryService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAKhD;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;;IAWG;;OAEG;iCAC0B,CAC3B,OAAO,EAAE,qBAAqB,KAC3B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC;IAExC;;OAEG;iCAC0B,CAC3B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,YAAY,EACpB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,KACR,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC;IAExC;;OAEG;8BACuB,CACxB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,KACR,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC;IAExC;;OAEG;2BACoB,CACrB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,OAAO,KAChB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC;IAExC;;OAEG;iCAC0B,CAC3B,OAAO,EAAE,MAAM,KACZ,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC;;AA5C5C,qBAAa,gBAAiB,SAAQ,qBA8CnC;IACD,MAAM,CAAC,IAAI,8CA0PR;CACJ"}
@@ -0,0 +1,201 @@
1
+ import { Effect, Context, Layer } from "effect";
2
+ import { execSync } from "child_process";
3
+ import * as fs from "fs/promises";
4
+ import * as path from "path";
5
+ const DirectoryError = (message, cause) => ({
6
+ _tag: "DirectoryError",
7
+ message,
8
+ cause,
9
+ });
10
+ export class DirectoryService extends Context.Tag("DirectoryService")() {
11
+ static Live = Layer.succeed(this, {
12
+ setupHomeDirectory: (options) => Effect.gen(function* () {
13
+ const { username, homeDir, uid, gid, claudeConfig } = options;
14
+ // Ensure home directory exists (should be created by useradd)
15
+ yield* Effect.tryPromise({
16
+ try: async () => {
17
+ await fs.access(homeDir);
18
+ },
19
+ catch: (error) => DirectoryError(`Home directory ${homeDir} does not exist. Create user first.`, error),
20
+ });
21
+ // Create .claude directory
22
+ const claudeDir = path.join(homeDir, ".claude");
23
+ yield* Effect.tryPromise({
24
+ try: async () => {
25
+ await fs.mkdir(claudeDir, { recursive: true, mode: 0o755 });
26
+ },
27
+ catch: (error) => DirectoryError(`Failed to create .claude directory`, error),
28
+ });
29
+ // Create subdirectories
30
+ const subdirs = ["sessions", "cache", "workspace"];
31
+ for (const subdir of subdirs) {
32
+ const subdirPath = subdir === "workspace"
33
+ ? path.join(homeDir, subdir)
34
+ : path.join(claudeDir, subdir);
35
+ yield* Effect.tryPromise({
36
+ try: async () => {
37
+ await fs.mkdir(subdirPath, { recursive: true, mode: 0o755 });
38
+ },
39
+ catch: (error) => DirectoryError(`Failed to create ${subdir} directory`, error),
40
+ });
41
+ }
42
+ // Create Claude config file
43
+ if (claudeConfig) {
44
+ const configPath = path.join(claudeDir, "config.json");
45
+ const configContent = JSON.stringify({
46
+ apiKey: claudeConfig.apiKey || "",
47
+ model: claudeConfig.model || "claude-sonnet-4-20250514",
48
+ maxTokens: claudeConfig.maxTokens || 8192,
49
+ temperature: claudeConfig.temperature || 1.0,
50
+ username,
51
+ createdAt: new Date().toISOString(),
52
+ }, null, 2);
53
+ yield* Effect.tryPromise({
54
+ try: async () => {
55
+ await fs.writeFile(configPath, configContent, {
56
+ mode: 0o600,
57
+ });
58
+ },
59
+ catch: (error) => DirectoryError("Failed to create Claude config file", error),
60
+ });
61
+ }
62
+ // Create .bashrc with helpful aliases
63
+ const bashrcPath = path.join(homeDir, ".bashrc");
64
+ const bashrcContent = `# MyAIDev Method User Environment
65
+ # Generated on ${new Date().toISOString()}
66
+
67
+ # Helpful aliases
68
+ alias ll='ls -alh'
69
+ alias workspace='cd ~/workspace'
70
+ alias claude='cd ~/.claude'
71
+
72
+ # Environment
73
+ export PATH="$HOME/.local/bin:$PATH"
74
+ export CLAUDE_CONFIG_DIR="$HOME/.claude"
75
+
76
+ # Workspace directory
77
+ export WORKSPACE="$HOME/workspace"
78
+
79
+ # Welcome message
80
+ echo "Welcome to MyAIDev Method, ${username}!"
81
+ echo "Your workspace is in: ~/workspace"
82
+ `;
83
+ yield* Effect.tryPromise({
84
+ try: async () => {
85
+ await fs.writeFile(bashrcPath, bashrcContent, { mode: 0o644 });
86
+ },
87
+ catch: (error) => DirectoryError("Failed to create .bashrc file", error),
88
+ });
89
+ // Set ownership of all created files/directories
90
+ yield* Effect.tryPromise({
91
+ try: async () => {
92
+ execSync(`sudo chown -R ${uid}:${gid} ${homeDir}`, {
93
+ stdio: "pipe",
94
+ });
95
+ },
96
+ catch: (error) => DirectoryError(`Failed to set ownership for ${homeDir}`, error),
97
+ });
98
+ // Set proper permissions
99
+ yield* Effect.tryPromise({
100
+ try: async () => {
101
+ execSync(`sudo chmod 755 ${homeDir}`, { stdio: "pipe" });
102
+ execSync(`sudo chmod 700 ${claudeDir}`, { stdio: "pipe" });
103
+ execSync(`sudo chmod 755 ${path.join(homeDir, "workspace")}`, {
104
+ stdio: "pipe",
105
+ });
106
+ },
107
+ catch: (error) => DirectoryError("Failed to set directory permissions", error),
108
+ });
109
+ }),
110
+ createClaudeConfig: (homeDir, config, uid, gid) => Effect.gen(function* () {
111
+ const claudeDir = path.join(homeDir, ".claude");
112
+ const configPath = path.join(claudeDir, "config.json");
113
+ // Ensure .claude directory exists
114
+ yield* Effect.tryPromise({
115
+ try: async () => {
116
+ await fs.mkdir(claudeDir, { recursive: true, mode: 0o700 });
117
+ },
118
+ catch: (error) => DirectoryError("Failed to create .claude directory", error),
119
+ });
120
+ // Write config file
121
+ const configContent = JSON.stringify(config, null, 2);
122
+ yield* Effect.tryPromise({
123
+ try: async () => {
124
+ await fs.writeFile(configPath, configContent, { mode: 0o600 });
125
+ },
126
+ catch: (error) => DirectoryError("Failed to write Claude config", error),
127
+ });
128
+ // Set ownership
129
+ yield* Effect.tryPromise({
130
+ try: async () => {
131
+ execSync(`sudo chown -R ${uid}:${gid} ${claudeDir}`, {
132
+ stdio: "pipe",
133
+ });
134
+ },
135
+ catch: (error) => DirectoryError("Failed to set config ownership", error),
136
+ });
137
+ }),
138
+ createWorkspace: (homeDir, uid, gid) => Effect.gen(function* () {
139
+ const workspaceDir = path.join(homeDir, "workspace");
140
+ // Create workspace directory
141
+ yield* Effect.tryPromise({
142
+ try: async () => {
143
+ await fs.mkdir(workspaceDir, { recursive: true, mode: 0o755 });
144
+ },
145
+ catch: (error) => DirectoryError("Failed to create workspace directory", error),
146
+ });
147
+ // Create a README file
148
+ const readmePath = path.join(workspaceDir, "README.md");
149
+ const readmeContent = `# Welcome to Your MyAIDev Method Workspace
150
+
151
+ This is your personal workspace for AI-assisted development with Claude Code.
152
+
153
+ ## Directory Structure
154
+
155
+ - Use this workspace to create and manage your projects
156
+ - Claude Code will have access to files in this directory
157
+ - Your work is isolated from other users
158
+
159
+ ## Getting Started
160
+
161
+ 1. Create a new project directory
162
+ 2. Initialize your project (git init, npm init, etc.)
163
+ 3. Start working with Claude Code assistance
164
+
165
+ Happy coding!
166
+ `;
167
+ yield* Effect.tryPromise({
168
+ try: async () => {
169
+ await fs.writeFile(readmePath, readmeContent, { mode: 0o644 });
170
+ },
171
+ catch: (error) => DirectoryError("Failed to create workspace README", error),
172
+ });
173
+ // Set ownership
174
+ yield* Effect.tryPromise({
175
+ try: async () => {
176
+ execSync(`sudo chown -R ${uid}:${gid} ${workspaceDir}`, {
177
+ stdio: "pipe",
178
+ });
179
+ },
180
+ catch: (error) => DirectoryError("Failed to set workspace ownership", error),
181
+ });
182
+ }),
183
+ setOwnership: (dirPath, uid, gid, recursive = false) => Effect.tryPromise({
184
+ try: async () => {
185
+ const recursiveFlag = recursive ? "-R" : "";
186
+ execSync(`sudo chown ${recursiveFlag} ${uid}:${gid} ${dirPath}`, {
187
+ stdio: "pipe",
188
+ });
189
+ },
190
+ catch: (error) => DirectoryError(`Failed to set ownership for ${dirPath}`, error),
191
+ }),
192
+ cleanupDirectories: (homeDir) => Effect.tryPromise({
193
+ try: async () => {
194
+ // Remove home directory and all contents
195
+ execSync(`sudo rm -rf ${homeDir}`, { stdio: "pipe" });
196
+ },
197
+ catch: (error) => DirectoryError(`Failed to cleanup directories for ${homeDir}`, error),
198
+ }),
199
+ });
200
+ }
201
+ //# sourceMappingURL=DirectoryService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DirectoryService.js","sourceRoot":"","sources":["../../../src/server/user-management/DirectoryService.ts"],"names":[],"mappings":"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"}