@loom-framework/core 0.1.0-alpha.149 → 0.1.0-alpha.150

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 (125) hide show
  1. package/builtin-skills/app-skill/SKILL.md +12 -7
  2. package/builtin-skills/app-skill/references/auth.md +164 -0
  3. package/builtin-skills/app-skill/references/models.md +2 -0
  4. package/builtin-skills/loom/SKILL.md +35 -3
  5. package/dist/backend/ai/engine.d.ts.map +1 -1
  6. package/dist/backend/ai/engine.js +1 -0
  7. package/dist/backend/ai/engine.js.map +1 -1
  8. package/dist/backend/auth/jwt.d.ts +16 -0
  9. package/dist/backend/auth/jwt.d.ts.map +1 -0
  10. package/dist/backend/auth/jwt.js +57 -0
  11. package/dist/backend/auth/jwt.js.map +1 -0
  12. package/dist/backend/auth/password.d.ts +10 -0
  13. package/dist/backend/auth/password.d.ts.map +1 -0
  14. package/dist/backend/auth/password.js +19 -0
  15. package/dist/backend/auth/password.js.map +1 -0
  16. package/dist/backend/auth/rbac.d.ts +34 -0
  17. package/dist/backend/auth/rbac.d.ts.map +1 -0
  18. package/dist/backend/auth/rbac.js +124 -0
  19. package/dist/backend/auth/rbac.js.map +1 -0
  20. package/dist/backend/auth/service-token.d.ts +11 -0
  21. package/dist/backend/auth/service-token.d.ts.map +1 -0
  22. package/dist/backend/auth/service-token.js +13 -0
  23. package/dist/backend/auth/service-token.js.map +1 -0
  24. package/dist/backend/auth/token-store.d.ts +27 -0
  25. package/dist/backend/auth/token-store.d.ts.map +1 -0
  26. package/dist/backend/auth/token-store.js +84 -0
  27. package/dist/backend/auth/token-store.js.map +1 -0
  28. package/dist/backend/auth/user-store.d.ts +41 -0
  29. package/dist/backend/auth/user-store.d.ts.map +1 -0
  30. package/dist/backend/auth/user-store.js +112 -0
  31. package/dist/backend/auth/user-store.js.map +1 -0
  32. package/dist/backend/index.d.ts +8 -0
  33. package/dist/backend/index.d.ts.map +1 -1
  34. package/dist/backend/index.js +48 -2
  35. package/dist/backend/index.js.map +1 -1
  36. package/dist/backend/routes/auth-routes.d.ts +26 -0
  37. package/dist/backend/routes/auth-routes.d.ts.map +1 -0
  38. package/dist/backend/routes/auth-routes.js +301 -0
  39. package/dist/backend/routes/auth-routes.js.map +1 -0
  40. package/dist/backend/routes/chat.d.ts.map +1 -1
  41. package/dist/backend/routes/chat.js +1 -0
  42. package/dist/backend/routes/chat.js.map +1 -1
  43. package/dist/backend/routes/data.d.ts.map +1 -1
  44. package/dist/backend/routes/data.js +8 -0
  45. package/dist/backend/routes/data.js.map +1 -1
  46. package/dist/backend/routes/index.d.ts +2 -0
  47. package/dist/backend/routes/index.d.ts.map +1 -1
  48. package/dist/backend/routes/index.js +1 -0
  49. package/dist/backend/routes/index.js.map +1 -1
  50. package/dist/cli/commands/auth.d.ts +11 -0
  51. package/dist/cli/commands/auth.d.ts.map +1 -0
  52. package/dist/cli/commands/auth.js +203 -0
  53. package/dist/cli/commands/auth.js.map +1 -0
  54. package/dist/cli/commands/data.d.ts +5 -1
  55. package/dist/cli/commands/data.d.ts.map +1 -1
  56. package/dist/cli/commands/data.js +182 -40
  57. package/dist/cli/commands/data.js.map +1 -1
  58. package/dist/cli/commands/generate-system-settings.d.ts +2 -2
  59. package/dist/cli/commands/generate-system-settings.d.ts.map +1 -1
  60. package/dist/cli/commands/generate-system-settings.js +14 -6
  61. package/dist/cli/commands/generate-system-settings.js.map +1 -1
  62. package/dist/cli/commands/init.js +26 -2
  63. package/dist/cli/commands/init.js.map +1 -1
  64. package/dist/cli/commands/role.d.ts +9 -0
  65. package/dist/cli/commands/role.d.ts.map +1 -0
  66. package/dist/cli/commands/role.js +81 -0
  67. package/dist/cli/commands/role.js.map +1 -0
  68. package/dist/cli/commands/user-cmd.d.ts +9 -0
  69. package/dist/cli/commands/user-cmd.d.ts.map +1 -0
  70. package/dist/cli/commands/user-cmd.js +204 -0
  71. package/dist/cli/commands/user-cmd.js.map +1 -0
  72. package/dist/cli/generators/capability-generator.d.ts.map +1 -1
  73. package/dist/cli/generators/capability-generator.js +67 -6
  74. package/dist/cli/generators/capability-generator.js.map +1 -1
  75. package/dist/cli/helpers/app-tsx-wiring.d.ts +7 -0
  76. package/dist/cli/helpers/app-tsx-wiring.d.ts.map +1 -1
  77. package/dist/cli/helpers/app-tsx-wiring.js +44 -0
  78. package/dist/cli/helpers/app-tsx-wiring.js.map +1 -1
  79. package/dist/cli/index.d.ts.map +1 -1
  80. package/dist/cli/index.js +6 -0
  81. package/dist/cli/index.js.map +1 -1
  82. package/dist/cli/lib/credentials.d.ts +27 -0
  83. package/dist/cli/lib/credentials.d.ts.map +1 -0
  84. package/dist/cli/lib/credentials.js +112 -0
  85. package/dist/cli/lib/credentials.js.map +1 -0
  86. package/dist/cli/templates/auth-wiring.d.ts +17 -0
  87. package/dist/cli/templates/auth-wiring.d.ts.map +1 -0
  88. package/dist/cli/templates/auth-wiring.js +31 -0
  89. package/dist/cli/templates/auth-wiring.js.map +1 -0
  90. package/dist/cli/templates/index.d.ts +2 -0
  91. package/dist/cli/templates/index.d.ts.map +1 -1
  92. package/dist/cli/templates/index.js +2 -0
  93. package/dist/cli/templates/index.js.map +1 -1
  94. package/dist/cli/templates/login-page.d.ts +5 -0
  95. package/dist/cli/templates/login-page.d.ts.map +1 -0
  96. package/dist/cli/templates/login-page.js +13 -0
  97. package/dist/cli/templates/login-page.js.map +1 -0
  98. package/dist/cli/templates/loom-config.d.ts.map +1 -1
  99. package/dist/cli/templates/loom-config.js +13 -0
  100. package/dist/cli/templates/loom-config.js.map +1 -1
  101. package/dist/cli/templates/model-management-page.d.ts.map +1 -1
  102. package/dist/cli/templates/model-management-page.js +6 -5
  103. package/dist/cli/templates/model-management-page.js.map +1 -1
  104. package/dist/cli/templates/user-management-page.d.ts +9 -0
  105. package/dist/cli/templates/user-management-page.d.ts.map +1 -0
  106. package/dist/cli/templates/user-management-page.js +236 -0
  107. package/dist/cli/templates/user-management-page.js.map +1 -0
  108. package/dist/config.d.ts +249 -1
  109. package/dist/config.d.ts.map +1 -1
  110. package/dist/config.js +28 -1
  111. package/dist/config.js.map +1 -1
  112. package/dist/index.d.ts +1 -1
  113. package/dist/index.d.ts.map +1 -1
  114. package/dist/index.js.map +1 -1
  115. package/dist/types/ai.d.ts +2 -0
  116. package/dist/types/ai.d.ts.map +1 -1
  117. package/dist/types/auth.d.ts +64 -0
  118. package/dist/types/auth.d.ts.map +1 -0
  119. package/dist/types/auth.js +5 -0
  120. package/dist/types/auth.js.map +1 -0
  121. package/dist/types/config.d.ts +2 -0
  122. package/dist/types/config.d.ts.map +1 -1
  123. package/dist/types/index.d.ts +1 -0
  124. package/dist/types/index.d.ts.map +1 -1
  125. package/package.json +5 -1
@@ -1,27 +1,32 @@
1
1
  ---
2
2
  name: {{projectName}}-data
3
3
  description: |
4
- [阅读 references/models.md 中的数据模型和 AI 按钮定义,编写触发短语。
5
- 包含:用户语言中的常见增删改查动词、各数据模型相关的操作、AI 按钮的标签。
4
+ ⚠️ TODO: 根据下方 [TODO] 标记补全触发短语。阅读 references/models.md 中的数据模型和 AI 按钮定义,
5
+ 编写触发短语,包含:用户语言中的常见增删改查动词、各数据模型相关的操作、AI 按钮的标签。
6
6
  格式:"This skill should be used when the user asks to '短语1', '短语2',
7
- or any request about <此项目管理的内容> in the {{projectName}} project."]
7
+ or any request about <此项目管理的内容> in the {{projectName}} project."
8
8
  version: 1.0.0
9
9
  ---
10
10
 
11
11
  # {{projectName}} — App Skill
12
12
 
13
+ > **此文件由 `loom generate capabilities` 生成。标记为 [TODO] 的部分需要手动编辑补全。**
14
+ > references/models.md 和 references/data-semantics.md 会每次重新生成,无需手动编辑。
15
+
13
16
  ## Overview
14
17
 
15
- [阅读 references/models.md,用2-3句话描述:项目做什么、管理哪些数据模型、用户如何通过 AI 对话与数据交互。]
18
+ [TODO: 阅读 references/models.md,用2-3句话描述项目做什么、管理哪些数据模型、用户如何通过 AI 对话与数据交互。]
16
19
 
17
20
  ## Usage Scenarios
18
21
 
19
- [**必须加载 references/models.md 和 references/data-semantics.md**,这两个文件包含从 loom.config.ts 动态注入的项目特定信息,不加载则无法生成正确内容。
22
+ **必须加载 references/models.md 和 references/data-semantics.md**,这两个文件包含从 loom.config.ts 动态注入的项目特定信息,不加载则无法生成正确内容:
20
23
  - models.md — 当前项目的数据模型字段表(字段名、类型、enum 取值、默认值)、AI 按钮定义(id、label、prompt、placement)、CLI 命令语法(read/write/update/delete,不要使用 create/list 等不存在的命令)。
21
24
  - data-semantics.md — 当前项目的数据模型名称列表、write 的 --data JSON 构造规则(字段类型格式、enum 取值约束、贴合业务的真实示例值)、read 的 --filter JSON 构造规则(优先用 enum/boolean 字段筛选、跨模型关联查询)。
22
- 再生成8-10个典型用户请求,每个格式:用户说的话 → 对应的 `loom data` CLI 命令。每个数据模型至少包含一个场景。]
25
+
26
+ [TODO: 生成8-10个典型用户请求,每个格式:用户说的话 → 对应的 `loom data` CLI 命令。每个数据模型至少包含一个场景。]
23
27
 
24
28
  ## Technical Reference
25
29
 
26
30
  - 数据模型结构、CLI 语法和操作规范:**references/models.md**
27
- - 语义引导(示例数据生成、筛选选择、关系推断):**references/data-semantics.md**
31
+ - 语义引导(示例数据生成、筛选选择、关系推断):**references/data-semantics.md**
32
+ <!-- AUTH_REF -->
@@ -0,0 +1,164 @@
1
+ # Auth Commands Reference
2
+
3
+ ## CLI Authentication
4
+
5
+ CLI commands require authentication when auth is enabled. Provide token via:
6
+
7
+ 1. **`--token` flag**: `loom data read <model> --token <jwt>`
8
+ 2. **`LOOM_TOKEN` env**: `LOOM_TOKEN=<jwt> loom data read <model>`
9
+
10
+ When auth is not enabled, CLI commands use local DataAdapter without token.
11
+
12
+ ### AI Chat Sessions
13
+
14
+ When using AI chat (web UI), `LOOM_TOKEN` is automatically set in the AI's environment.
15
+ AI can run `loom data read`, `loom user list`, etc. directly — the token matches the logged-in user's identity and permissions.
16
+
17
+ ## Authentication Commands
18
+
19
+ ### Login
20
+ ```bash
21
+ loom auth login -u <username> -p <password>
22
+ loom auth login # interactive prompt
23
+ ```
24
+
25
+ ### Register (admin token required)
26
+ ```bash
27
+ loom auth register -u <username> -p <password> [--role <role>] --token <admin-jwt>
28
+ ```
29
+
30
+ ### Logout
31
+ ```bash
32
+ loom auth logout --refresh-token <token> --token <jwt>
33
+ ```
34
+
35
+ ### Whoami
36
+ ```bash
37
+ loom auth whoami --token <jwt>
38
+ ```
39
+
40
+ ## User Management (Admin Only)
41
+
42
+ ### Add User
43
+ ```bash
44
+ loom user add <username> -p <password> -r <role> --token <admin-jwt>
45
+ ```
46
+
47
+ ### List Users
48
+ ```bash
49
+ loom user list --token <jwt>
50
+ ```
51
+
52
+ ### Update User
53
+ ```bash
54
+ loom user update <id> -r <role> --token <jwt>
55
+ loom user update <id> -p <newpassword> --token <jwt>
56
+ ```
57
+
58
+ ### Delete User
59
+ ```bash
60
+ loom user delete <id> --token <admin-jwt>
61
+ ```
62
+
63
+ ### Change Role
64
+ ```bash
65
+ loom user role <id> <role> --token <admin-jwt>
66
+ ```
67
+
68
+ ## Role Info
69
+
70
+ ### List Roles
71
+ ```bash
72
+ loom role list [--token <jwt>]
73
+ ```
74
+
75
+ ### Permission Levels
76
+ ```bash
77
+ loom role permissions
78
+ ```
79
+
80
+ ## Data Commands with Auth
81
+
82
+ When auth is enabled, data commands route through HTTP API and require token:
83
+
84
+ ```bash
85
+ loom data read <model> --token <jwt>
86
+ loom data write <model> --data '<json>' --token <jwt>
87
+ loom data update <model> --id <id> --data '<json>' --token <jwt>
88
+ loom data delete <model> --id <id> --token <jwt>
89
+ loom data schema <model> --token <jwt>
90
+ ```
91
+
92
+ Optional: `--server <url>` (default: http://localhost:3000)
93
+
94
+ ## Permission Model
95
+
96
+ ### Levels (hierarchical)
97
+ | Level | Access |
98
+ |-------|--------|
99
+ | `none` | No access |
100
+ | `read` | GET (read-only) |
101
+ | `write` | GET, POST, PUT |
102
+ | `admin` | GET, POST, PUT, DELETE |
103
+
104
+ ### Configuration in loom.config.ts
105
+ ```typescript
106
+ auth: {
107
+ provider: 'builtin',
108
+ secret: 'env:JWT_SECRET', // or plain string (not recommended)
109
+ roles: [
110
+ { role: 'admin', permissions: [{ model: '*', level: 'admin' }] },
111
+ { role: 'editor', permissions: [{ model: 'items', level: 'write' }] },
112
+ { role: 'viewer', permissions: [{ model: '*', level: 'read' }] },
113
+ ],
114
+ permissions: {
115
+ defaults: {
116
+ read: 'read',
117
+ write: 'write',
118
+ readIncludesAiButtons: false, // viewer sees AI buttons?
119
+ writeExcludesDelete: false, // writer can delete?
120
+ },
121
+ },
122
+ }
123
+ ```
124
+
125
+ ### Wildcard Permissions
126
+ Use `model: '*'` to apply a permission level to all models.
127
+ Explicit model permissions override wildcards.
128
+
129
+ ### Default Admin User
130
+ When auth is first enabled, a default admin user is created:
131
+ - Username: `admin`
132
+ - Password: `admin123`
133
+ - **Change this immediately after first login!**
134
+
135
+ ### Service Token
136
+ Each user gets a service token at registration time (long-lived JWT, 30-day TTL).
137
+ Returned in the API response when creating a user — the admin should save it securely.
138
+ Used by Process automation to execute as the user.
139
+
140
+ ## API Endpoints
141
+
142
+ | Method | Path | Auth | Description |
143
+ |--------|------|------|-------------|
144
+ | POST | /api/v1/auth/login | No | Login |
145
+ | POST | /api/v1/auth/register | Admin | Register new user |
146
+ | POST | /api/v1/auth/logout | Yes | Logout |
147
+ | POST | /api/v1/auth/refresh | No* | Refresh token |
148
+ | GET | /api/v1/auth/whoami | Yes | Current user |
149
+ | GET | /api/v1/auth/roles | Yes | List roles |
150
+ | GET | /api/v1/auth/users | Admin | List users |
151
+ | POST | /api/v1/auth/users | Admin | Create user |
152
+ | GET | /api/v1/auth/users/:id | Self/Admin | Get user |
153
+ | PUT | /api/v1/auth/users/:id | Self/Admin | Update user |
154
+ | DELETE | /api/v1/auth/users/:id | Admin | Delete user |
155
+
156
+ *Refresh requires valid refresh token in store
157
+
158
+ ## Audit Fields
159
+
160
+ When auth is enabled, write operations automatically inject:
161
+ - `createdBy` — username of the user who created the record (POST)
162
+ - `updatedBy` — username of the user who last updated the record (PUT)
163
+
164
+ These fields are optional and don't affect existing data.
@@ -20,6 +20,8 @@
20
20
 
21
21
  <!-- AI_BUTTONS -->
22
22
 
23
+ <!-- AUTH_ROLES -->
24
+
23
25
  ## 操作规范
24
26
 
25
27
  1. 所有数据操作必须使用 `loom data` CLI 命令,不要直接访问文件或数据库。
@@ -65,9 +65,10 @@ loom generate capabilities
65
65
 
66
66
  | 文件 | 说明 | 覆盖策略 |
67
67
  |------|------|---------|
68
- | `SKILL.md` | Skill 主文档(含 TODO 模板) | 仅首次创建,不覆盖 |
68
+ | `SKILL.md` | Skill 主文档(含 TODO 模板) | 仅首次创建,不覆盖。若需重建:删除整个 skill 目录后重新执行 |
69
69
  | `references/models.md` | 数据模型字段表 + AI 按钮定义 + CLI 语法 | 每次重新生成 |
70
70
  | `references/data-semantics.md` | 语义引导(示例数据、筛选规则、跨模型关联) | 每次重新生成 |
71
+ | `references/auth.md` | 认证鉴权命令参考(`--token`/`LOOM_TOKEN` 用法、权限模型) | Auth 启用时每次重新生成 |
71
72
 
72
73
  每次修改数据模型或 AI 按钮后,重新运行此命令即可更新 `references/` 下的自动生成内容,`SKILL.md` 中手动补充的内容不会被覆盖。
73
74
 
@@ -95,6 +96,19 @@ loom generate dashboard <name>
95
96
 
96
97
  此命令从 `loom.config.ts` 的 `dashboards` 字段读取配置,自动生成 Dashboard 页面并接线 App.tsx。
97
98
 
99
+ ### 5.5 启用认证鉴权(可选)
100
+
101
+ 当用户需要多用户支持、权限控制时,帮助用户在 `loom.config.ts` 中添加 `auth` 配置:
102
+
103
+ 1. **询问需求**:是否需要登录功能?有哪些角色?每个角色能做什么?
104
+ 2. **编辑配置**:在 `loom.config.ts` 中添加 `auth` 字段(Schema 见上方)。至少定义一个 `admin` 角色
105
+ 3. **设置密钥**:`secret` 推荐 `env:JWT_SECRET`,不要硬编码。提醒用户设置环境变量 `export JWT_SECRET=your-secret`
106
+ 4. **重启后端**:auth 配置需要重启后端生效(**必须先询问用户**)
107
+ 5. **首次登录**:默认创建 admin 用户(密码 `admin123`),**提醒用户立即修改密码**
108
+ 6. **生成 app-skill**:`loom generate capabilities` 更新 Skill 中的 auth.md
109
+
110
+ 启用后自动获得:登录页 + 路由守卫 + RBAC 权限控制 + 用户管理页 + CLI `--token`/`LOOM_TOKEN` 鉴权。
111
+
98
112
  ### 重启服务前必须询问用户
99
113
 
100
114
  修改 `loom.config.ts` 后如果需要重启后端服务(如增删 AI 按钮、修改 enum 值、新增模型等场景),**必须先询问用户是否可以重启**,得到确认后再执行 `loom dev` 或停止/重启服务。不要自动重启,因为用户可能正在使用页面或调试中。
@@ -149,8 +163,8 @@ loom generate page <Name> --model <model-name> --force
149
163
  | `loom generate capabilities` | 生成应用 Skill(`references/models.md` + `references/data-semantics.md`,`SKILL.md` 仅首次创建不覆盖) |
150
164
  | `loom generate dashboard <name>` | 从 loom.config.ts dashboards 生成 Dashboard 页面 |
151
165
  | `loom generate dashboard <name> --force` | 重建 Dashboard 页面(自动备份旧文件到 `.loom/backup/`) |
152
- | `loom generate system-settings <model\|skill>` | 生成系统管理页面(模型管理或技能管理),首次调用创建子菜单,后续调用追加子页面 |
153
- | `loom generate system-settings <model\|skill> --force` | 重建系统管理页面(自动备份旧文件到 `.loom/backup/`) |
166
+ | `loom generate system-settings <model\|skill\|user>` | 生成系统管理页面(模型管理、技能管理或用户管理),首次调用创建子菜单,后续调用追加子页面 |
167
+ | `loom generate system-settings <model\|skill\|user> --force` | 重建系统管理页面(自动备份旧文件到 `.loom/backup/`) |
154
168
  | `loom generate skill <name>` | 生成自定义 Skill 脚架 |
155
169
 
156
170
  ## loom.config.ts Schema(核心)
@@ -201,6 +215,24 @@ export default defineConfig({
201
215
  filterDimensions: [], // 可选:启用下拉筛选,见 references/dashboard.md
202
216
  layout: [{ row: [{ type: 'stat', title: { 'zh-CN': '总数', 'en-US': 'Total' }, model: 'items', aggregate: 'count', span: 6 }] }],
203
217
  }],
218
+ auth: { // 可选:认证与鉴权,启用后生成登录页、用户管理、RBAC 权限控制
219
+ provider: 'builtin', // 'builtin' — 内置认证
220
+ secret: 'env:JWT_SECRET', // JWT 签名密钥,推荐用 env: 引用环境变量,不要硬编码
221
+ accessTokenTtl: 3600, // 可选,access token 有效期(秒),默认 3600(1h)
222
+ refreshTokenTtl: 604800, // 可选,refresh token 有效期(秒),默认 604800(7d)
223
+ roles: [ // 角色定义,至少一个 admin 角色
224
+ { role: 'admin', permissions: [{ model: '*', level: 'admin' }] },
225
+ { role: 'viewer', permissions: [{ model: '*', level: 'read' }] },
226
+ ],
227
+ permissions: { // 可选:默认权限和行为配置
228
+ defaults: {
229
+ read: 'read', // 未显式配置的模型默认读权限
230
+ write: 'write', // 未显式配置的模型默认写权限
231
+ readIncludesAiButtons: false, // read 权限是否可见 AI 按钮
232
+ writeExcludesDelete: false, // write 权限是否排除删除操作
233
+ },
234
+ },
235
+ },
204
236
  });
205
237
  ```
206
238
 
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/backend/ai/engine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAM5F,wCAAwC;AACxC,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,cAAc,GAAG,iBAAiB,GAAG,QAAQ,GAAG,cAAc,CAAC;AAEnH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AAE3D,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,gBAAgB,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,QAAQ,CAAC,IAAI,iBAAiB;IAE9B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,MAAM,CAAC,CAAe;gBAElB,OAAO,EAAE,uBAAuB;IAM5C,OAAO,CAAC,GAAG;IAUX;;OAEG;IACI,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,cAAc,CAAC,OAAO,CAAC;IAmJ5E;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAUvC;;OAEG;IACH,OAAO,IAAI,IAAI;CAQhB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAC5C,MAAM,CAQR"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/backend/ai/engine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAM5F,wCAAwC;AACxC,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,cAAc,GAAG,iBAAiB,GAAG,QAAQ,GAAG,cAAc,CAAC;AAEnH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AAE3D,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,gBAAgB,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,QAAQ,CAAC,IAAI,iBAAiB;IAE9B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,MAAM,CAAC,CAAe;gBAElB,OAAO,EAAE,uBAAuB;IAM5C,OAAO,CAAC,GAAG;IAUX;;OAEG;IACI,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,cAAc,CAAC,OAAO,CAAC;IAoJ5E;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAUvC;;OAEG;IACH,OAAO,IAAI,IAAI;CAQhB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAC5C,MAAM,CAQR"}
@@ -92,6 +92,7 @@ export class ClaudeCodeEngine {
92
92
  env: {
93
93
  ...process.env,
94
94
  CLAUDE_PLUGIN_ROOT: pluginRoot,
95
+ ...(options.userToken ? { LOOM_TOKEN: options.userToken } : {}),
95
96
  },
96
97
  });
97
98
  // Track active process for cleanup
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/backend/ai/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/backend/ai/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * JWT token utilities
3
+ */
4
+ import type { AuthConfig } from '../../types/auth.js';
5
+ export interface TokenPayload {
6
+ userId: string;
7
+ username: string;
8
+ role: string;
9
+ }
10
+ export declare function signAccessToken(session: TokenPayload, config: AuthConfig): string;
11
+ export declare function signRefreshToken(session: TokenPayload, config: AuthConfig): string;
12
+ export declare function signServiceToken(session: TokenPayload, config: AuthConfig): string;
13
+ export declare function verifyToken(token: string, config: AuthConfig): TokenPayload;
14
+ export declare function refreshAccessToken(refreshToken: string, config: AuthConfig): string;
15
+ export declare function isTokenExpired(token: string): boolean;
16
+ //# sourceMappingURL=jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/backend/auth/jwt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAMtD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAcD,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAIjF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAIlF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAGlF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,YAAY,CAI3E;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAOnF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAQrD"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * JWT token utilities
3
+ */
4
+ import jwt from 'jsonwebtoken';
5
+ const DEFAULT_ACCESS_TTL = 900;
6
+ const DEFAULT_REFRESH_TTL = 604800;
7
+ const DEFAULT_SERVICE_TTL = 2592000; // 30 days
8
+ function resolveSecret(secret) {
9
+ if (secret.startsWith('env:')) {
10
+ const envVar = secret.slice(4);
11
+ const value = process.env[envVar];
12
+ if (!value) {
13
+ throw new Error(`JWT secret environment variable ${envVar} is not set`);
14
+ }
15
+ return value;
16
+ }
17
+ return secret;
18
+ }
19
+ export function signAccessToken(session, config) {
20
+ const secret = resolveSecret(config.secret);
21
+ const ttl = config.accessTokenTtl ?? DEFAULT_ACCESS_TTL;
22
+ return jwt.sign(session, secret, { expiresIn: ttl });
23
+ }
24
+ export function signRefreshToken(session, config) {
25
+ const secret = resolveSecret(config.secret);
26
+ const ttl = config.refreshTokenTtl ?? DEFAULT_REFRESH_TTL;
27
+ return jwt.sign({ ...session, type: 'refresh' }, secret, { expiresIn: ttl });
28
+ }
29
+ export function signServiceToken(session, config) {
30
+ const secret = resolveSecret(config.secret);
31
+ return jwt.sign({ ...session, type: 'service' }, secret, { expiresIn: DEFAULT_SERVICE_TTL });
32
+ }
33
+ export function verifyToken(token, config) {
34
+ const secret = resolveSecret(config.secret);
35
+ const decoded = jwt.verify(token, secret);
36
+ return decoded;
37
+ }
38
+ export function refreshAccessToken(refreshToken, config) {
39
+ const payload = verifyToken(refreshToken, config);
40
+ if (payload.type !== 'refresh') {
41
+ throw new Error('Not a refresh token');
42
+ }
43
+ const { type: _, exp: __, iat: ___, ...session } = payload;
44
+ return signAccessToken(session, config);
45
+ }
46
+ export function isTokenExpired(token) {
47
+ try {
48
+ const decoded = jwt.decode(token);
49
+ if (!decoded?.exp)
50
+ return true;
51
+ return decoded.exp * 1000 < Date.now();
52
+ }
53
+ catch {
54
+ return true;
55
+ }
56
+ }
57
+ //# sourceMappingURL=jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../../src/backend/auth/jwt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Password hashing and verification utilities
3
+ */
4
+ export declare function validatePasswordStrength(password: string): {
5
+ valid: boolean;
6
+ message?: string;
7
+ };
8
+ export declare function hashPassword(password: string): Promise<string>;
9
+ export declare function verifyPassword(password: string, hash: string): Promise<boolean>;
10
+ //# sourceMappingURL=password.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../../src/backend/auth/password.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAK/F;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEpE;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAErF"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Password hashing and verification utilities
3
+ */
4
+ import bcrypt from 'bcryptjs';
5
+ const SALT_ROUNDS = 12;
6
+ const MIN_PASSWORD_LENGTH = 8;
7
+ export function validatePasswordStrength(password) {
8
+ if (!password || password.length < MIN_PASSWORD_LENGTH) {
9
+ return { valid: false, message: `Password must be at least ${MIN_PASSWORD_LENGTH} characters` };
10
+ }
11
+ return { valid: true };
12
+ }
13
+ export async function hashPassword(password) {
14
+ return bcrypt.hash(password, SALT_ROUNDS);
15
+ }
16
+ export async function verifyPassword(password, hash) {
17
+ return bcrypt.compare(password, hash);
18
+ }
19
+ //# sourceMappingURL=password.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.js","sourceRoot":"","sources":["../../../src/backend/auth/password.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,MAAM,MAAM,UAAU,CAAC;AAE9B,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IACvD,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,mBAAmB,EAAE,CAAC;QACvD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,6BAA6B,mBAAmB,aAAa,EAAE,CAAC;IAClG,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB,EAAE,IAAY;IACjE,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * RBAC Middleware
3
+ *
4
+ * Two-layer auth:
5
+ * 1. Routes with :model param → model-level permission check
6
+ * 2. Routes without :model param → binary authentication (just verify logged in)
7
+ *
8
+ * Exempt routes: login, register, refresh
9
+ */
10
+ import type { FastifyRequest, FastifyReply } from 'fastify';
11
+ import type { AuthConfig, AuthPermissionLevel } from '../../types/auth.js';
12
+ /** Resolve required permission level for a method, respecting writeExcludesDelete config */
13
+ export declare function getRequiredLevel(method: string, config: AuthConfig): AuthPermissionLevel;
14
+ /** Resolve effective permission for a model given user role and config */
15
+ export declare function resolvePermission(model: string, roleName: string, config: AuthConfig): AuthPermissionLevel;
16
+ /** Check if user level meets required level */
17
+ export declare function hasPermission(userLevel: AuthPermissionLevel, requiredLevel: AuthPermissionLevel): boolean;
18
+ /** Extend FastifyRequest with user info */
19
+ declare module 'fastify' {
20
+ interface FastifyRequest {
21
+ user?: {
22
+ userId: string;
23
+ username: string;
24
+ role: string;
25
+ /** Raw JWT token for passing to child processes (e.g. LOOM_TOKEN for AI engine) */
26
+ token?: string;
27
+ };
28
+ }
29
+ }
30
+ export interface AuthMiddlewareOptions {
31
+ config: AuthConfig;
32
+ }
33
+ export declare function createAuthMiddleware(options: AuthMiddlewareOptions): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
34
+ //# sourceMappingURL=rbac.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rbac.d.ts","sourceRoot":"","sources":["../../../src/backend/auth/rbac.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAwB,MAAM,qBAAqB,CAAC;AAoBjG,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,mBAAmB,CAOxF;AASD,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,GACjB,mBAAmB,CAcrB;AAED,+CAA+C;AAC/C,wBAAgB,aAAa,CAAC,SAAS,EAAE,mBAAmB,EAAE,aAAa,EAAE,mBAAmB,GAAG,OAAO,CAEzG;AAED,2CAA2C;AAC3C,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,IAAI,CAAC,EAAE;YACL,MAAM,EAAE,MAAM,CAAC;YACf,QAAQ,EAAE,MAAM,CAAC;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,mFAAmF;YACnF,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB,CAAC;KACH;CACF;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,IAGnD,SAAS,cAAc,EAAE,OAAO,YAAY,mBA8D3D"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * RBAC Middleware
3
+ *
4
+ * Two-layer auth:
5
+ * 1. Routes with :model param → model-level permission check
6
+ * 2. Routes without :model param → binary authentication (just verify logged in)
7
+ *
8
+ * Exempt routes: login, register, refresh
9
+ */
10
+ import { verifyToken } from './jwt.js';
11
+ /** Permission hierarchy: none < read < write < admin */
12
+ const LEVEL_HIERARCHY = {
13
+ none: 0,
14
+ read: 1,
15
+ write: 2,
16
+ admin: 3,
17
+ };
18
+ /** HTTP method → minimum permission level for model routes (base, before writeExcludesDelete override) */
19
+ const BASE_METHOD_LEVEL = {
20
+ GET: 'read',
21
+ POST: 'write',
22
+ PUT: 'write',
23
+ PATCH: 'write',
24
+ DELETE: 'admin',
25
+ };
26
+ /** Resolve required permission level for a method, respecting writeExcludesDelete config */
27
+ export function getRequiredLevel(method, config) {
28
+ const base = BASE_METHOD_LEVEL[method] ?? 'read';
29
+ // writeExcludesDelete defaults to false: write level includes delete unless explicitly set to true
30
+ if (method === 'DELETE' && config.permissions.defaults.writeExcludesDelete !== true) {
31
+ return 'write';
32
+ }
33
+ return base;
34
+ }
35
+ /** Exempt paths (no auth required) */
36
+ const EXEMPT_PATHS = [
37
+ '/api/v1/auth/login',
38
+ '/api/v1/auth/register',
39
+ '/api/v1/auth/refresh',
40
+ ];
41
+ /** Resolve effective permission for a model given user role and config */
42
+ export function resolvePermission(model, roleName, config) {
43
+ const role = config.roles.find(r => r.role === roleName);
44
+ if (!role)
45
+ return config.permissions.defaults.read;
46
+ // Check explicit model permission
47
+ const modelPerm = role.permissions.find(p => p.model === model);
48
+ if (modelPerm)
49
+ return modelPerm.level;
50
+ // Check wildcard permission
51
+ const wildcardPerm = role.permissions.find(p => p.model === '*');
52
+ if (wildcardPerm)
53
+ return wildcardPerm.level;
54
+ // Fall back to defaults based on method
55
+ return config.permissions.defaults.read;
56
+ }
57
+ /** Check if user level meets required level */
58
+ export function hasPermission(userLevel, requiredLevel) {
59
+ return LEVEL_HIERARCHY[userLevel] >= LEVEL_HIERARCHY[requiredLevel];
60
+ }
61
+ export function createAuthMiddleware(options) {
62
+ const { config } = options;
63
+ return async (request, reply) => {
64
+ // Skip exempt paths (exact match or path boundary)
65
+ if (EXEMPT_PATHS.some(p => {
66
+ if (request.url === p)
67
+ return true;
68
+ if (request.url.startsWith(p + '/') || request.url.startsWith(p + '?'))
69
+ return true;
70
+ return false;
71
+ })) {
72
+ return;
73
+ }
74
+ // Extract and verify token
75
+ const authHeader = request.headers.authorization;
76
+ if (!authHeader?.startsWith('Bearer ')) {
77
+ reply.code(401).send({ error: 'Authentication required' });
78
+ return;
79
+ }
80
+ const token = authHeader.slice(7);
81
+ try {
82
+ const payload = verifyToken(token, config);
83
+ // Reject refresh tokens used for API access
84
+ if (payload.type === 'refresh') {
85
+ reply.code(401).send({ error: 'Refresh tokens cannot be used for API access' });
86
+ return;
87
+ }
88
+ request.user = {
89
+ userId: payload.userId,
90
+ username: payload.username,
91
+ role: payload.role,
92
+ token,
93
+ };
94
+ }
95
+ catch {
96
+ reply.code(401).send({ error: 'Invalid or expired token' });
97
+ return;
98
+ }
99
+ // Model-level permission check (for routes with :model param)
100
+ const model = request.params?.model;
101
+ if (model) {
102
+ const method = request.method;
103
+ const requiredLevel = getRequiredLevel(method, config);
104
+ const userLevel = resolvePermission(model, request.user.role, config);
105
+ if (!hasPermission(userLevel, requiredLevel)) {
106
+ request.log.warn({
107
+ userId: request.user?.userId,
108
+ role: request.user?.role,
109
+ model,
110
+ method: request.method,
111
+ required: requiredLevel,
112
+ actual: userLevel,
113
+ }, 'Auth: permission denied');
114
+ reply.code(403).send({
115
+ error: 'Insufficient permissions',
116
+ required: requiredLevel,
117
+ actual: userLevel,
118
+ });
119
+ return;
120
+ }
121
+ }
122
+ };
123
+ }
124
+ //# sourceMappingURL=rbac.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rbac.js","sourceRoot":"","sources":["../../../src/backend/auth/rbac.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Service Token management
3
+ *
4
+ * Issues service tokens for Process automation and CLI auth.
5
+ * Service tokens are long-lived (30d), not affected by password changes.
6
+ * Returned via API response on user creation — caller is responsible for storage.
7
+ */
8
+ import type { AuthConfig } from '../../types/auth.js';
9
+ /** Issue a service token for the given user (does not persist to file) */
10
+ export declare function issueServiceToken(userId: string, username: string, role: string, config: AuthConfig): string;
11
+ //# sourceMappingURL=service-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-token.d.ts","sourceRoot":"","sources":["../../../src/backend/auth/service-token.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,GACjB,MAAM,CAER"}