@ai-partner-x/aiko-boot-cli 0.1.4

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 (389) hide show
  1. package/README.md +187 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +30 -0
  4. package/dist/commands/add-api.d.ts +5 -0
  5. package/dist/commands/add-api.js +34 -0
  6. package/dist/commands/add-app.d.ts +5 -0
  7. package/dist/commands/add-app.js +34 -0
  8. package/dist/commands/add-feature.d.ts +5 -0
  9. package/dist/commands/add-feature.js +32 -0
  10. package/dist/commands/init.d.ts +7 -0
  11. package/dist/commands/init.js +42 -0
  12. package/dist/commands/list.d.ts +6 -0
  13. package/dist/commands/list.js +36 -0
  14. package/dist/core/framework-version.d.ts +8 -0
  15. package/dist/core/framework-version.js +40 -0
  16. package/dist/core/logger.d.ts +6 -0
  17. package/dist/core/logger.js +16 -0
  18. package/dist/core/project-config.d.ts +21 -0
  19. package/dist/core/project-config.js +17 -0
  20. package/dist/core/prompts.d.ts +5 -0
  21. package/dist/core/prompts.js +43 -0
  22. package/dist/core/template-utils.d.ts +1 -0
  23. package/dist/core/template-utils.js +42 -0
  24. package/dist/core/workspace.d.ts +10 -0
  25. package/dist/core/workspace.js +141 -0
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.js +2 -0
  28. package/dist/scaffold.d.ts +7 -0
  29. package/dist/scaffold.js +272 -0
  30. package/dist/usecases/add-api.usecase.d.ts +16 -0
  31. package/dist/usecases/add-api.usecase.js +87 -0
  32. package/dist/usecases/add-app.usecase.d.ts +16 -0
  33. package/dist/usecases/add-app.usecase.js +101 -0
  34. package/dist/usecases/add-feature.usecase.d.ts +15 -0
  35. package/dist/usecases/add-feature.usecase.js +566 -0
  36. package/dist/usecases/init-scaffold.usecase.d.ts +19 -0
  37. package/dist/usecases/init-scaffold.usecase.js +131 -0
  38. package/package.json +43 -0
  39. package/templates/api-base/app.config.ts +155 -0
  40. package/templates/api-base/package.json +55 -0
  41. package/templates/api-base/scripts/codegen.cjs +30 -0
  42. package/templates/api-base/scripts/codegen.ts +10 -0
  43. package/templates/api-base/src/controller/auth.controller.ts +160 -0
  44. package/templates/api-base/src/controller/menu.controller.ts +56 -0
  45. package/templates/api-base/src/controller/role.controller.ts +62 -0
  46. package/templates/api-base/src/controller/user.controller.ts +75 -0
  47. package/templates/api-base/src/dto/auth.dto.ts +31 -0
  48. package/templates/api-base/src/dto/menu.dto.ts +38 -0
  49. package/templates/api-base/src/dto/role.dto.ts +18 -0
  50. package/templates/api-base/src/dto/user.dto.ts +36 -0
  51. package/templates/api-base/src/entity/menu.entity.ts +35 -0
  52. package/templates/api-base/src/entity/role-menu.entity.ts +14 -0
  53. package/templates/api-base/src/entity/role.entity.ts +23 -0
  54. package/templates/api-base/src/entity/user-role.entity.ts +14 -0
  55. package/templates/api-base/src/entity/user.entity.ts +32 -0
  56. package/templates/api-base/src/mapper/menu.mapper.ts +7 -0
  57. package/templates/api-base/src/mapper/role-menu.mapper.ts +7 -0
  58. package/templates/api-base/src/mapper/role.mapper.ts +7 -0
  59. package/templates/api-base/src/mapper/user-role.mapper.ts +7 -0
  60. package/templates/api-base/src/mapper/user.mapper.ts +12 -0
  61. package/templates/api-base/src/scripts/init-db.ts +204 -0
  62. package/templates/api-base/src/server.ts +69 -0
  63. package/templates/api-base/src/service/auth.service.ts +144 -0
  64. package/templates/api-base/src/service/log.request.service.ts +72 -0
  65. package/templates/api-base/src/service/menu.service.ts +94 -0
  66. package/templates/api-base/src/service/role.service.ts +88 -0
  67. package/templates/api-base/src/service/user.service.ts +175 -0
  68. package/templates/api-base/src/utils/jwt.util.ts +39 -0
  69. package/templates/api-base/tsconfig.json +18 -0
  70. package/templates/feature-file/api/upload.controller.ts +97 -0
  71. package/templates/feature-log/api/docs/log-integration-guide.md +54 -0
  72. package/templates/feature-log/api/src/service/log.request.service.ts +112 -0
  73. package/templates/feature-log/api/src/service/log.service.ts +124 -0
  74. package/templates/feature-mq/api/src/controller/mq.controller.ts +35 -0
  75. package/templates/feature-mq/api/src/dto/mq.dto.ts +16 -0
  76. package/templates/feature-mq/api/src/service/mq.consumer.service.ts +26 -0
  77. package/templates/feature-redis/api/src/controller/cache.controller.ts +107 -0
  78. package/templates/feature-redis/api/src/dto/cache.dto.ts +24 -0
  79. package/templates/feature-redis/api/src/service/cache.service.ts +80 -0
  80. package/templates/scaffold-default/README.md +114 -0
  81. package/templates/scaffold-default/package.json +26 -0
  82. package/templates/scaffold-default/packages/admin/.env.dev +1 -0
  83. package/templates/scaffold-default/packages/admin/.env.prod +4 -0
  84. package/templates/scaffold-default/packages/admin/.env.stage +4 -0
  85. package/templates/scaffold-default/packages/admin/Dockerfile +37 -0
  86. package/templates/scaffold-default/packages/admin/README.MD +27 -0
  87. package/templates/scaffold-default/packages/admin/components.json +21 -0
  88. package/templates/scaffold-default/packages/admin/eslint.config.js +28 -0
  89. package/templates/scaffold-default/packages/admin/index.html +50 -0
  90. package/templates/scaffold-default/packages/admin/package.json +100 -0
  91. package/templates/scaffold-default/packages/admin/public/vite.svg +1 -0
  92. package/templates/scaffold-default/packages/admin/src/App.css +82 -0
  93. package/templates/scaffold-default/packages/admin/src/App.tsx +128 -0
  94. package/templates/scaffold-default/packages/admin/src/app.config.ts +3 -0
  95. package/templates/scaffold-default/packages/admin/src/components/admin-ui/data-table/data-table-pagination.tsx +148 -0
  96. package/templates/scaffold-default/packages/admin/src/components/admin-ui/data-table/data-table-sorter.tsx +50 -0
  97. package/templates/scaffold-default/packages/admin/src/components/admin-ui/data-table/index.tsx +266 -0
  98. package/templates/scaffold-default/packages/admin/src/components/admin-ui/editable-table.tsx +292 -0
  99. package/templates/scaffold-default/packages/admin/src/components/admin-ui/form/input-password.tsx +38 -0
  100. package/templates/scaffold-default/packages/admin/src/components/admin-ui/form/sign-in-form.tsx +118 -0
  101. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/error-component.tsx +71 -0
  102. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/header.tsx +162 -0
  103. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/language-switcher.tsx +47 -0
  104. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/layout.tsx +42 -0
  105. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/loading-overlay.tsx +36 -0
  106. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/shell-bar.tsx +232 -0
  107. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/sidebar.tsx +193 -0
  108. package/templates/scaffold-default/packages/admin/src/components/admin-ui/layout/user-avatar.tsx +31 -0
  109. package/templates/scaffold-default/packages/admin/src/components/admin-ui/list-report.tsx +306 -0
  110. package/templates/scaffold-default/packages/admin/src/components/admin-ui/master-detail.tsx +382 -0
  111. package/templates/scaffold-default/packages/admin/src/components/admin-ui/notification/toaster.tsx +23 -0
  112. package/templates/scaffold-default/packages/admin/src/components/admin-ui/notification/undoable-notification.tsx +84 -0
  113. package/templates/scaffold-default/packages/admin/src/components/admin-ui/object-page.tsx +539 -0
  114. package/templates/scaffold-default/packages/admin/src/components/admin-ui/theme/theme-provider.tsx +160 -0
  115. package/templates/scaffold-default/packages/admin/src/components/admin-ui/theme/theme-select.tsx +129 -0
  116. package/templates/scaffold-default/packages/admin/src/components/admin-ui/theme/theme-toggle.tsx +90 -0
  117. package/templates/scaffold-default/packages/admin/src/components/ui/accordion.tsx +64 -0
  118. package/templates/scaffold-default/packages/admin/src/components/ui/alert-dialog.tsx +157 -0
  119. package/templates/scaffold-default/packages/admin/src/components/ui/alert.tsx +66 -0
  120. package/templates/scaffold-default/packages/admin/src/components/ui/aspect-ratio.tsx +9 -0
  121. package/templates/scaffold-default/packages/admin/src/components/ui/avatar.tsx +53 -0
  122. package/templates/scaffold-default/packages/admin/src/components/ui/badge.tsx +47 -0
  123. package/templates/scaffold-default/packages/admin/src/components/ui/breadcrumb.tsx +111 -0
  124. package/templates/scaffold-default/packages/admin/src/components/ui/button.tsx +59 -0
  125. package/templates/scaffold-default/packages/admin/src/components/ui/calendar.tsx +74 -0
  126. package/templates/scaffold-default/packages/admin/src/components/ui/card.tsx +92 -0
  127. package/templates/scaffold-default/packages/admin/src/components/ui/carousel.tsx +237 -0
  128. package/templates/scaffold-default/packages/admin/src/components/ui/chart.tsx +351 -0
  129. package/templates/scaffold-default/packages/admin/src/components/ui/checkbox.tsx +32 -0
  130. package/templates/scaffold-default/packages/admin/src/components/ui/collapsible.tsx +33 -0
  131. package/templates/scaffold-default/packages/admin/src/components/ui/command.tsx +182 -0
  132. package/templates/scaffold-default/packages/admin/src/components/ui/context-menu.tsx +252 -0
  133. package/templates/scaffold-default/packages/admin/src/components/ui/dialog.tsx +141 -0
  134. package/templates/scaffold-default/packages/admin/src/components/ui/drawer.tsx +130 -0
  135. package/templates/scaffold-default/packages/admin/src/components/ui/dropdown-menu.tsx +255 -0
  136. package/templates/scaffold-default/packages/admin/src/components/ui/form.tsx +166 -0
  137. package/templates/scaffold-default/packages/admin/src/components/ui/hover-card.tsx +42 -0
  138. package/templates/scaffold-default/packages/admin/src/components/ui/input-otp.tsx +77 -0
  139. package/templates/scaffold-default/packages/admin/src/components/ui/input.tsx +21 -0
  140. package/templates/scaffold-default/packages/admin/src/components/ui/label.tsx +22 -0
  141. package/templates/scaffold-default/packages/admin/src/components/ui/menubar.tsx +274 -0
  142. package/templates/scaffold-default/packages/admin/src/components/ui/navigation-menu.tsx +168 -0
  143. package/templates/scaffold-default/packages/admin/src/components/ui/pagination.tsx +127 -0
  144. package/templates/scaffold-default/packages/admin/src/components/ui/popover.tsx +48 -0
  145. package/templates/scaffold-default/packages/admin/src/components/ui/progress.tsx +29 -0
  146. package/templates/scaffold-default/packages/admin/src/components/ui/radio-group.tsx +45 -0
  147. package/templates/scaffold-default/packages/admin/src/components/ui/resizable.tsx +54 -0
  148. package/templates/scaffold-default/packages/admin/src/components/ui/scroll-area.tsx +58 -0
  149. package/templates/scaffold-default/packages/admin/src/components/ui/select.tsx +183 -0
  150. package/templates/scaffold-default/packages/admin/src/components/ui/separator.tsx +26 -0
  151. package/templates/scaffold-default/packages/admin/src/components/ui/sheet.tsx +139 -0
  152. package/templates/scaffold-default/packages/admin/src/components/ui/sidebar.tsx +740 -0
  153. package/templates/scaffold-default/packages/admin/src/components/ui/skeleton.tsx +13 -0
  154. package/templates/scaffold-default/packages/admin/src/components/ui/slider.tsx +63 -0
  155. package/templates/scaffold-default/packages/admin/src/components/ui/sonner.tsx +23 -0
  156. package/templates/scaffold-default/packages/admin/src/components/ui/switch.tsx +31 -0
  157. package/templates/scaffold-default/packages/admin/src/components/ui/table.tsx +114 -0
  158. package/templates/scaffold-default/packages/admin/src/components/ui/tabs.tsx +66 -0
  159. package/templates/scaffold-default/packages/admin/src/components/ui/textarea.tsx +18 -0
  160. package/templates/scaffold-default/packages/admin/src/components/ui/toggle-group.tsx +73 -0
  161. package/templates/scaffold-default/packages/admin/src/components/ui/toggle.tsx +45 -0
  162. package/templates/scaffold-default/packages/admin/src/components/ui/tooltip.tsx +59 -0
  163. package/templates/scaffold-default/packages/admin/src/hooks/use-mobile.ts +21 -0
  164. package/templates/scaffold-default/packages/admin/src/i18n.ts +20 -0
  165. package/templates/scaffold-default/packages/admin/src/index.tsx +19 -0
  166. package/templates/scaffold-default/packages/admin/src/layouts/menu-layout.tsx +211 -0
  167. package/templates/scaffold-default/packages/admin/src/layouts/tile-layout.tsx +355 -0
  168. package/templates/scaffold-default/packages/admin/src/lib/utils.ts +6 -0
  169. package/templates/scaffold-default/packages/admin/src/locales/en.json +68 -0
  170. package/templates/scaffold-default/packages/admin/src/locales/zh.json +68 -0
  171. package/templates/scaffold-default/packages/admin/src/pages/dashboard.tsx +12 -0
  172. package/templates/scaffold-default/packages/admin/src/pages/goods-receipt/CreatePage.tsx +302 -0
  173. package/templates/scaffold-default/packages/admin/src/pages/goods-receipt/EditPage.tsx +221 -0
  174. package/templates/scaffold-default/packages/admin/src/pages/goods-receipt/ListPage.tsx +283 -0
  175. package/templates/scaffold-default/packages/admin/src/pages/goods-receipt/ViewPage.tsx +280 -0
  176. package/templates/scaffold-default/packages/admin/src/pages/goods-receipt/index.ts +4 -0
  177. package/templates/scaffold-default/packages/admin/src/pages/home-page.tsx +244 -0
  178. package/templates/scaffold-default/packages/admin/src/pages/master-data/cost-centers/index.tsx +461 -0
  179. package/templates/scaffold-default/packages/admin/src/pages/master-data/currencies/index.tsx +255 -0
  180. package/templates/scaffold-default/packages/admin/src/pages/master-data/materials/ListPage.tsx +271 -0
  181. package/templates/scaffold-default/packages/admin/src/pages/master-data/materials/ViewPage.tsx +240 -0
  182. package/templates/scaffold-default/packages/admin/src/pages/master-data/materials/index.ts +2 -0
  183. package/templates/scaffold-default/packages/admin/src/pages/master-data/plants/ListPage.tsx +279 -0
  184. package/templates/scaffold-default/packages/admin/src/pages/master-data/plants/ViewPage.tsx +380 -0
  185. package/templates/scaffold-default/packages/admin/src/pages/master-data/plants/index.ts +2 -0
  186. package/templates/scaffold-default/packages/admin/src/pages/master-data/purchase-organizations/index.tsx +341 -0
  187. package/templates/scaffold-default/packages/admin/src/pages/master-data/units-of-measure/index.tsx +295 -0
  188. package/templates/scaffold-default/packages/admin/src/pages/master-data/vendors/ListPage.tsx +266 -0
  189. package/templates/scaffold-default/packages/admin/src/pages/master-data/vendors/ViewPage.tsx +274 -0
  190. package/templates/scaffold-default/packages/admin/src/pages/master-data/vendors/index.ts +2 -0
  191. package/templates/scaffold-default/packages/admin/src/pages/placeholder-page.tsx +13 -0
  192. package/templates/scaffold-default/packages/admin/src/pages/purchase-orders/ListPage.tsx +289 -0
  193. package/templates/scaffold-default/packages/admin/src/pages/purchase-orders/ViewPage.tsx +343 -0
  194. package/templates/scaffold-default/packages/admin/src/pages/purchase-orders/index.ts +2 -0
  195. package/templates/scaffold-default/packages/admin/src/pages/purchase-requisitions/CreatePage.tsx +398 -0
  196. package/templates/scaffold-default/packages/admin/src/pages/purchase-requisitions/EditPage.tsx +473 -0
  197. package/templates/scaffold-default/packages/admin/src/pages/purchase-requisitions/ListPage.tsx +307 -0
  198. package/templates/scaffold-default/packages/admin/src/pages/purchase-requisitions/ViewPage.tsx +304 -0
  199. package/templates/scaffold-default/packages/admin/src/pages/purchase-requisitions/constants.ts +51 -0
  200. package/templates/scaffold-default/packages/admin/src/pages/purchase-requisitions/index.ts +4 -0
  201. package/templates/scaffold-default/packages/admin/src/pages/reports/PurchaseOrderReport.tsx +312 -0
  202. package/templates/scaffold-default/packages/admin/src/pages/reports/PurchaseRequisitionReport.tsx +303 -0
  203. package/templates/scaffold-default/packages/admin/src/pages/reports/index.ts +2 -0
  204. package/templates/scaffold-default/packages/admin/src/pages/settings-page.tsx +335 -0
  205. package/templates/scaffold-default/packages/admin/src/providers/app-config.tsx +50 -0
  206. package/templates/scaffold-default/packages/admin/src/providers/auth-provider.ts +2 -0
  207. package/templates/scaffold-default/packages/admin/src/routes/auth.ts +9 -0
  208. package/templates/scaffold-default/packages/admin/src/routes/index.ts +85 -0
  209. package/templates/scaffold-default/packages/admin/src/routes/menu.ts +176 -0
  210. package/templates/scaffold-default/packages/admin/src/routes/modules/goods-receipt.ts +31 -0
  211. package/templates/scaffold-default/packages/admin/src/routes/modules/master-data.ts +41 -0
  212. package/templates/scaffold-default/packages/admin/src/routes/modules/purchase-orders.ts +27 -0
  213. package/templates/scaffold-default/packages/admin/src/routes/modules/purchase-requisitions.ts +39 -0
  214. package/templates/scaffold-default/packages/admin/src/routes/modules/reports.ts +33 -0
  215. package/templates/scaffold-default/packages/admin/src/routes/modules/settings.ts +19 -0
  216. package/templates/scaffold-default/packages/admin/src/routes/withSuspense.tsx +21 -0
  217. package/templates/scaffold-default/packages/admin/src/theme/amber.css +27 -0
  218. package/templates/scaffold-default/packages/admin/src/theme/blue.css +27 -0
  219. package/templates/scaffold-default/packages/admin/src/theme/default.css +75 -0
  220. package/templates/scaffold-default/packages/admin/src/theme/fiori.css +180 -0
  221. package/templates/scaffold-default/packages/admin/src/theme/green.css +27 -0
  222. package/templates/scaffold-default/packages/admin/src/theme/index.css +12 -0
  223. package/templates/scaffold-default/packages/admin/src/theme/rose.css +27 -0
  224. package/templates/scaffold-default/packages/admin/src/theme/violet.css +27 -0
  225. package/templates/scaffold-default/packages/admin/src/vite-env.d.ts +1 -0
  226. package/templates/scaffold-default/packages/admin/tsconfig.json +28 -0
  227. package/templates/scaffold-default/packages/admin/tsconfig.node.json +21 -0
  228. package/templates/scaffold-default/packages/admin/vite.config.ts +26 -0
  229. package/templates/scaffold-default/packages/api/.eslintrc.json +6 -0
  230. package/templates/scaffold-default/packages/api/.swcrc +17 -0
  231. package/templates/scaffold-default/packages/api/app.config.ts +163 -0
  232. package/templates/scaffold-default/packages/api/docs/api-document.md +497 -0
  233. package/templates/scaffold-default/packages/api/docs/final-completion-report.md +565 -0
  234. package/templates/scaffold-default/packages/api/docs/permission-integration-summary.md +432 -0
  235. package/templates/scaffold-default/packages/api/examples/security/README.md +664 -0
  236. package/templates/scaffold-default/packages/api/examples/security/complete/.env.example +26 -0
  237. package/templates/scaffold-default/packages/api/examples/security/complete/PROJECT_STRUCTURE.md +220 -0
  238. package/templates/scaffold-default/packages/api/examples/security/complete/README.md +847 -0
  239. package/templates/scaffold-default/packages/api/examples/security/complete/app.config.ts +69 -0
  240. package/templates/scaffold-default/packages/api/examples/security/complete/app.ts +63 -0
  241. package/templates/scaffold-default/packages/api/examples/security/complete/controller/auth.controller.ts +131 -0
  242. package/templates/scaffold-default/packages/api/examples/security/complete/controller/index.ts +4 -0
  243. package/templates/scaffold-default/packages/api/examples/security/complete/controller/permission.controller.ts +41 -0
  244. package/templates/scaffold-default/packages/api/examples/security/complete/controller/role.controller.ts +53 -0
  245. package/templates/scaffold-default/packages/api/examples/security/complete/controller/user.controller.ts +53 -0
  246. package/templates/scaffold-default/packages/api/examples/security/complete/dto/change-password.dto.ts +10 -0
  247. package/templates/scaffold-default/packages/api/examples/security/complete/dto/create-permission.dto.ts +14 -0
  248. package/templates/scaffold-default/packages/api/examples/security/complete/dto/create-role.dto.ts +11 -0
  249. package/templates/scaffold-default/packages/api/examples/security/complete/dto/create-user.dto.ts +15 -0
  250. package/templates/scaffold-default/packages/api/examples/security/complete/dto/index.ts +7 -0
  251. package/templates/scaffold-default/packages/api/examples/security/complete/dto/login.dto.ts +10 -0
  252. package/templates/scaffold-default/packages/api/examples/security/complete/dto/oauth-profile.dto.ts +7 -0
  253. package/templates/scaffold-default/packages/api/examples/security/complete/dto/register.dto.ts +17 -0
  254. package/templates/scaffold-default/packages/api/examples/security/complete/entity/index.ts +6 -0
  255. package/templates/scaffold-default/packages/api/examples/security/complete/entity/oauth-account.entity.ts +39 -0
  256. package/templates/scaffold-default/packages/api/examples/security/complete/entity/permission.entity.ts +31 -0
  257. package/templates/scaffold-default/packages/api/examples/security/complete/entity/role-permission.entity.ts +19 -0
  258. package/templates/scaffold-default/packages/api/examples/security/complete/entity/role.entity.ts +25 -0
  259. package/templates/scaffold-default/packages/api/examples/security/complete/entity/user-role.entity.ts +19 -0
  260. package/templates/scaffold-default/packages/api/examples/security/complete/entity/user.entity.ts +46 -0
  261. package/templates/scaffold-default/packages/api/examples/security/complete/init.sql +81 -0
  262. package/templates/scaffold-default/packages/api/examples/security/complete/middleware/auth.interceptor.ts +39 -0
  263. package/templates/scaffold-default/packages/api/examples/security/complete/middleware/index.ts +2 -0
  264. package/templates/scaffold-default/packages/api/examples/security/complete/middleware/permission.interceptor.ts +61 -0
  265. package/templates/scaffold-default/packages/api/examples/security/complete/package.json +54 -0
  266. package/templates/scaffold-default/packages/api/examples/security/complete/seed.sql +42 -0
  267. package/templates/scaffold-default/packages/api/examples/security/complete/service/auth.service.ts +41 -0
  268. package/templates/scaffold-default/packages/api/examples/security/complete/service/index.ts +5 -0
  269. package/templates/scaffold-default/packages/api/examples/security/complete/service/oauth.service.ts +82 -0
  270. package/templates/scaffold-default/packages/api/examples/security/complete/service/permission.service.ts +113 -0
  271. package/templates/scaffold-default/packages/api/examples/security/complete/service/role.service.ts +85 -0
  272. package/templates/scaffold-default/packages/api/examples/security/complete/service/user.service.ts +132 -0
  273. package/templates/scaffold-default/packages/api/examples/security/complete/tests/TEST_REPORT.md +318 -0
  274. package/templates/scaffold-default/packages/api/examples/security/complete/tests/generate-report.js +335 -0
  275. package/templates/scaffold-default/packages/api/examples/security/complete/tests/helpers/api-helpers.ts +116 -0
  276. package/templates/scaffold-default/packages/api/examples/security/complete/tests/helpers/index.ts +2 -0
  277. package/templates/scaffold-default/packages/api/examples/security/complete/tests/helpers/test-helpers.ts +129 -0
  278. package/templates/scaffold-default/packages/api/examples/security/complete/tests/integration/auth.api.test.ts +429 -0
  279. package/templates/scaffold-default/packages/api/examples/security/complete/tests/integration/role.api.test.ts +400 -0
  280. package/templates/scaffold-default/packages/api/examples/security/complete/tests/integration/user.api.test.ts +459 -0
  281. package/templates/scaffold-default/packages/api/examples/security/complete/tests/jest.config.js +40 -0
  282. package/templates/scaffold-default/packages/api/examples/security/complete/tests/run-all-tests.js +135 -0
  283. package/templates/scaffold-default/packages/api/examples/security/complete/tests/run-tests.js +109 -0
  284. package/templates/scaffold-default/packages/api/examples/security/complete/tests/setup.ts +19 -0
  285. package/templates/scaffold-default/packages/api/examples/security/complete/tests/unit/auth.service.test.ts +199 -0
  286. package/templates/scaffold-default/packages/api/examples/security/complete/tests/unit/permission.service.test.ts +377 -0
  287. package/templates/scaffold-default/packages/api/examples/security/complete/tests/unit/user.service.test.ts +288 -0
  288. package/templates/scaffold-default/packages/api/examples/security/complete/tsconfig.json +35 -0
  289. package/templates/scaffold-default/packages/api/examples/security/jwt/README.md +424 -0
  290. package/templates/scaffold-default/packages/api/examples/security/local/README.md +499 -0
  291. package/templates/scaffold-default/packages/api/examples/security/oauth2/README.md +637 -0
  292. package/templates/scaffold-default/packages/api/examples/security/permission/README.md +943 -0
  293. package/templates/scaffold-default/packages/api/examples/security/session/README.md +753 -0
  294. package/templates/scaffold-default/packages/api/package.json +63 -0
  295. package/templates/scaffold-default/packages/api/scripts/codegen.cjs +29 -0
  296. package/templates/scaffold-default/packages/api/scripts/codegen.ts +9 -0
  297. package/templates/scaffold-default/packages/api/src/config/security-auto-configuration.ts +75 -0
  298. package/templates/scaffold-default/packages/api/src/controller/auth.controller.ts +109 -0
  299. package/templates/scaffold-default/packages/api/src/controller/cache.controller.ts +106 -0
  300. package/templates/scaffold-default/packages/api/src/controller/menu.controller.ts +86 -0
  301. package/templates/scaffold-default/packages/api/src/controller/mq.controller.ts +35 -0
  302. package/templates/scaffold-default/packages/api/src/controller/role.controller.ts +100 -0
  303. package/templates/scaffold-default/packages/api/src/controller/upload.controller.ts +83 -0
  304. package/templates/scaffold-default/packages/api/src/controller/user.controller.ts +102 -0
  305. package/templates/scaffold-default/packages/api/src/dto/auth.dto.ts +30 -0
  306. package/templates/scaffold-default/packages/api/src/dto/cache.dto.ts +24 -0
  307. package/templates/scaffold-default/packages/api/src/dto/menu.dto.ts +37 -0
  308. package/templates/scaffold-default/packages/api/src/dto/mq.dto.ts +16 -0
  309. package/templates/scaffold-default/packages/api/src/dto/role.dto.ts +16 -0
  310. package/templates/scaffold-default/packages/api/src/dto/user.dto.ts +35 -0
  311. package/templates/scaffold-default/packages/api/src/entity/menu.entity.ts +34 -0
  312. package/templates/scaffold-default/packages/api/src/entity/role-menu.entity.ts +13 -0
  313. package/templates/scaffold-default/packages/api/src/entity/role.entity.ts +22 -0
  314. package/templates/scaffold-default/packages/api/src/entity/user-role.entity.ts +13 -0
  315. package/templates/scaffold-default/packages/api/src/entity/user.entity.ts +31 -0
  316. package/templates/scaffold-default/packages/api/src/mapper/menu.mapper.ts +6 -0
  317. package/templates/scaffold-default/packages/api/src/mapper/role-menu.mapper.ts +6 -0
  318. package/templates/scaffold-default/packages/api/src/mapper/role.mapper.ts +6 -0
  319. package/templates/scaffold-default/packages/api/src/mapper/user-role.mapper.ts +6 -0
  320. package/templates/scaffold-default/packages/api/src/mapper/user.mapper.ts +11 -0
  321. package/templates/scaffold-default/packages/api/src/scripts/assign-role.ts +41 -0
  322. package/templates/scaffold-default/packages/api/src/scripts/check-user-role.ts +28 -0
  323. package/templates/scaffold-default/packages/api/src/scripts/check-users.mjs +44 -0
  324. package/templates/scaffold-default/packages/api/src/scripts/demo-permissions.mjs +418 -0
  325. package/templates/scaffold-default/packages/api/src/scripts/init-db.ts +166 -0
  326. package/templates/scaffold-default/packages/api/src/scripts/reset-admin-password.mjs +70 -0
  327. package/templates/scaffold-default/packages/api/src/scripts/reset-password.ts +31 -0
  328. package/templates/scaffold-default/packages/api/src/scripts/simple-reset-admin.mjs +39 -0
  329. package/templates/scaffold-default/packages/api/src/scripts/test-db.ts +36 -0
  330. package/templates/scaffold-default/packages/api/src/scripts/test-di.ts +45 -0
  331. package/templates/scaffold-default/packages/api/src/scripts/test-permissions.mjs +551 -0
  332. package/templates/scaffold-default/packages/api/src/scripts/update-admin-password.mjs +56 -0
  333. package/templates/scaffold-default/packages/api/src/scripts/user-roles.ts +28 -0
  334. package/templates/scaffold-default/packages/api/src/server.ts +38 -0
  335. package/templates/scaffold-default/packages/api/src/service/auth.service.ts +165 -0
  336. package/templates/scaffold-default/packages/api/src/service/cache.service.ts +80 -0
  337. package/templates/scaffold-default/packages/api/src/service/log.request.service.ts +158 -0
  338. package/templates/scaffold-default/packages/api/src/service/log.service.ts +123 -0
  339. package/templates/scaffold-default/packages/api/src/service/menu.service.ts +94 -0
  340. package/templates/scaffold-default/packages/api/src/service/mq.consumer.service.ts +26 -0
  341. package/templates/scaffold-default/packages/api/src/service/role.service.ts +88 -0
  342. package/templates/scaffold-default/packages/api/src/service/user.service.ts +195 -0
  343. package/templates/scaffold-default/packages/api/src/types/sqljs.d.ts +18 -0
  344. package/templates/scaffold-default/packages/api/src/utils/auth.utils.js +0 -0
  345. package/templates/scaffold-default/packages/api/src/utils/jwt.util.ts +29 -0
  346. package/templates/scaffold-default/packages/api/tsconfig.json +17 -0
  347. package/templates/scaffold-default/packages/api/tsup.config.ts +14 -0
  348. package/templates/scaffold-default/packages/api/uploads/.gitkeep +0 -0
  349. package/templates/scaffold-default/packages/core/package.json +28 -0
  350. package/templates/scaffold-default/packages/core/src/auth/auth-client-middleware.ts +22 -0
  351. package/templates/scaffold-default/packages/core/src/auth/auth-constants.ts +6 -0
  352. package/templates/scaffold-default/packages/core/src/auth/auth-service.ts +65 -0
  353. package/templates/scaffold-default/packages/core/src/auth/backend-auth-provider.ts +149 -0
  354. package/templates/scaffold-default/packages/core/src/auth/default-auth-provider.ts +38 -0
  355. package/templates/scaffold-default/packages/core/src/auth/index.ts +12 -0
  356. package/templates/scaffold-default/packages/core/src/auth/types.ts +38 -0
  357. package/templates/scaffold-default/packages/core/src/authorization/authorization-client-middleware.ts +38 -0
  358. package/templates/scaffold-default/packages/core/src/authorization/authorization-config.ts +13 -0
  359. package/templates/scaffold-default/packages/core/src/authorization/authorization-provider.tsx +116 -0
  360. package/templates/scaffold-default/packages/core/src/authorization/default-authorization-provider.ts +26 -0
  361. package/templates/scaffold-default/packages/core/src/authorization/index.ts +15 -0
  362. package/templates/scaffold-default/packages/core/src/authorization/types.ts +42 -0
  363. package/templates/scaffold-default/packages/core/src/index.ts +3 -0
  364. package/templates/scaffold-default/packages/core/src/utils/promise-result-cache.ts +18 -0
  365. package/templates/scaffold-default/packages/core/tsconfig.json +19 -0
  366. package/templates/scaffold-default/packages/mobile/README.md +56 -0
  367. package/templates/scaffold-default/packages/mobile/index.html +13 -0
  368. package/templates/scaffold-default/packages/mobile/package.json +28 -0
  369. package/templates/scaffold-default/packages/mobile/postcss.config.mjs +7 -0
  370. package/templates/scaffold-default/packages/mobile/src/App.tsx +5 -0
  371. package/templates/scaffold-default/packages/mobile/src/app/globals.css +1 -0
  372. package/templates/scaffold-default/packages/mobile/src/components/LoginForm.tsx +83 -0
  373. package/templates/scaffold-default/packages/mobile/src/hooks/index.ts +5 -0
  374. package/templates/scaffold-default/packages/mobile/src/lib/utils.ts +7 -0
  375. package/templates/scaffold-default/packages/mobile/src/main.tsx +19 -0
  376. package/templates/scaffold-default/packages/mobile/src/pages/HomePage.tsx +41 -0
  377. package/templates/scaffold-default/packages/mobile/src/pages/LoginPage.tsx +24 -0
  378. package/templates/scaffold-default/packages/mobile/src/pages/index.ts +2 -0
  379. package/templates/scaffold-default/packages/mobile/src/routes/ProtectedRoute.tsx +35 -0
  380. package/templates/scaffold-default/packages/mobile/src/routes/index.tsx +24 -0
  381. package/templates/scaffold-default/packages/mobile/src/routes/routes.ts +11 -0
  382. package/templates/scaffold-default/packages/mobile/src/types/index.ts +5 -0
  383. package/templates/scaffold-default/packages/mobile/src/vite-env.d.ts +1 -0
  384. package/templates/scaffold-default/packages/mobile/tsconfig.json +23 -0
  385. package/templates/scaffold-default/packages/mobile/tsconfig.node.json +11 -0
  386. package/templates/scaffold-default/packages/mobile/vite.config.ts +20 -0
  387. package/templates/scaffold-default/pnpm-workspace.yaml +2 -0
  388. package/templates/scaffold-default/scripts/postinstall.cjs +42 -0
  389. package/templates/scaffold-default/scripts/rebuild-sqlite.cjs +23 -0
@@ -0,0 +1,46 @@
1
+ import { Entity, TableId, TableField, Column } from '@ai-partner-x/aiko-boot-starter-orm';
2
+
3
+ @Entity({ tableName: 'users' })
4
+ export class User {
5
+ @TableId()
6
+ id!: number;
7
+
8
+ @TableField()
9
+ @Column()
10
+ username!: string;
11
+
12
+ @TableField()
13
+ @Column()
14
+ email!: string;
15
+
16
+ @TableField()
17
+ @Column()
18
+ password!: string;
19
+
20
+ @TableField()
21
+ @Column()
22
+ enabled!: boolean;
23
+
24
+ @TableField()
25
+ @Column()
26
+ provider!: string;
27
+
28
+ @TableField()
29
+ @Column()
30
+ providerId!: string;
31
+
32
+ @TableField()
33
+ @Column()
34
+ avatar!: string;
35
+
36
+ @TableField()
37
+ @Column()
38
+ createdAt!: Date;
39
+
40
+ @TableField()
41
+ @Column()
42
+ updatedAt!: Date;
43
+
44
+ roles?: Role[];
45
+ permissions?: Permission[];
46
+ }
@@ -0,0 +1,81 @@
1
+ -- 创建用户表
2
+ CREATE TABLE IF NOT EXISTS users (
3
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
4
+ username TEXT NOT NULL UNIQUE,
5
+ email TEXT NOT NULL UNIQUE,
6
+ password TEXT NOT NULL,
7
+ enabled INTEGER DEFAULT 1,
8
+ provider TEXT DEFAULT 'local',
9
+ providerId TEXT DEFAULT '',
10
+ avatar TEXT DEFAULT '',
11
+ createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
12
+ updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP
13
+ );
14
+
15
+ -- 创建角色表
16
+ CREATE TABLE IF NOT EXISTS roles (
17
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
18
+ name TEXT NOT NULL UNIQUE,
19
+ description TEXT,
20
+ createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
21
+ updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP
22
+ );
23
+
24
+ -- 创建权限表
25
+ CREATE TABLE IF NOT EXISTS permissions (
26
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
27
+ name TEXT NOT NULL UNIQUE,
28
+ description TEXT,
29
+ resource TEXT NOT NULL,
30
+ action TEXT NOT NULL,
31
+ createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
32
+ updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP
33
+ );
34
+
35
+ -- 创建用户角色关联表
36
+ CREATE TABLE IF NOT EXISTS user_roles (
37
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
38
+ userId INTEGER NOT NULL,
39
+ roleId INTEGER NOT NULL,
40
+ createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
41
+ FOREIGN KEY (userId) REFERENCES users(id) ON DELETE CASCADE,
42
+ FOREIGN KEY (roleId) REFERENCES roles(id) ON DELETE CASCADE,
43
+ UNIQUE(userId, roleId)
44
+ );
45
+
46
+ -- 创建角色权限关联表
47
+ CREATE TABLE IF NOT EXISTS role_permissions (
48
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
49
+ roleId INTEGER NOT NULL,
50
+ permissionId INTEGER NOT NULL,
51
+ createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
52
+ FOREIGN KEY (roleId) REFERENCES roles(id) ON DELETE CASCADE,
53
+ FOREIGN KEY (permissionId) REFERENCES permissions(id) ON DELETE CASCADE,
54
+ UNIQUE(roleId, permissionId)
55
+ );
56
+
57
+ -- 创建 OAuth 账户表
58
+ CREATE TABLE IF NOT EXISTS oauth_accounts (
59
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
60
+ userId INTEGER NOT NULL,
61
+ provider TEXT NOT NULL,
62
+ providerId TEXT NOT NULL,
63
+ accessToken TEXT NOT NULL,
64
+ refreshToken TEXT DEFAULT '',
65
+ expiresAt DATETIME,
66
+ createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
67
+ updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
68
+ FOREIGN KEY (userId) REFERENCES users(id) ON DELETE CASCADE,
69
+ UNIQUE(provider, providerId)
70
+ );
71
+
72
+ -- 创建索引
73
+ CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
74
+ CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
75
+ CREATE INDEX IF NOT EXISTS idx_users_provider ON users(provider, providerId);
76
+ CREATE INDEX IF NOT EXISTS idx_user_roles_userId ON user_roles(userId);
77
+ CREATE INDEX IF NOT EXISTS idx_user_roles_roleId ON user_roles(roleId);
78
+ CREATE INDEX IF NOT EXISTS idx_role_permissions_roleId ON role_permissions(roleId);
79
+ CREATE INDEX IF NOT EXISTS idx_role_permissions_permissionId ON role_permissions(permissionId);
80
+ CREATE INDEX IF NOT EXISTS idx_oauth_accounts_userId ON oauth_accounts(userId);
81
+ CREATE INDEX IF NOT EXISTS idx_oauth_accounts_provider ON oauth_accounts(provider, providerId);
@@ -0,0 +1,39 @@
1
+ import { Injectable, Singleton, Autowired } from '@ai-partner-x/aiko-boot';
2
+ import { SecurityContext } from '@ai-partner-x/aiko-boot-starter-security';
3
+ import { JwtStrategy } from '@ai-partner-x/aiko-boot-starter-security';
4
+ import { SessionStrategy } from '@ai-partner-x/aiko-boot-starter-security';
5
+ import type { Request, Response, NextFunction } from 'express';
6
+
7
+ @Injectable()
8
+ @Singleton()
9
+ export class AuthInterceptor {
10
+ @Autowired()
11
+ private jwtStrategy!: JwtStrategy;
12
+
13
+ @Autowired()
14
+ private sessionStrategy!: SessionStrategy;
15
+
16
+ async intercept(req: Request, res: Response, next: NextFunction): Promise<void> {
17
+ const securityContext = SecurityContext.getInstance();
18
+
19
+ try {
20
+ let user = null;
21
+
22
+ if (req.headers.authorization && req.headers.authorization.startsWith('Bearer ')) {
23
+ const token = req.headers.authorization.substring(7);
24
+ user = await this.jwtStrategy.validate(token);
25
+ } else if (req.session && req.session.userId) {
26
+ user = await this.sessionStrategy.authenticate(req);
27
+ }
28
+
29
+ if (user) {
30
+ securityContext.setCurrentUser(user);
31
+ }
32
+
33
+ next();
34
+ } catch (error) {
35
+ console.error('Auth error:', error);
36
+ res.status(401).json({ error: '未授权' });
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,2 @@
1
+ export { AuthInterceptor } from './auth.interceptor.js';
2
+ export { PermissionInterceptor } from './permission.interceptor.js';
@@ -0,0 +1,61 @@
1
+ import { Injectable, Singleton, Autowired } from '@ai-partner-x/aiko-boot';
2
+ import { SecurityContext } from '@ai-partner-x/aiko-boot-starter-security';
3
+ import { PermissionService } from '../service/permission.service.js';
4
+ import { PermissionExpressionParser } from '@ai-partner-x/aiko-boot-starter-security';
5
+ import type { Request, Response, NextFunction } from 'express';
6
+
7
+ @Injectable()
8
+ @Singleton()
9
+ export class PermissionInterceptor {
10
+ @Autowired()
11
+ private permissionService!: PermissionService;
12
+
13
+ private parser = new PermissionExpressionParser();
14
+
15
+ async intercept(req: Request, res: Response, next: NextFunction): Promise<void> {
16
+ const securityContext = SecurityContext.getInstance();
17
+ const currentUser = securityContext.getCurrentUser();
18
+
19
+ if (!currentUser) {
20
+ return res.status(401).json({ error: '未授权' });
21
+ }
22
+
23
+ const permissionExpression = this.getPermissionExpression(req);
24
+
25
+ if (permissionExpression) {
26
+ const hasPermission = await this.parser.evaluate(
27
+ permissionExpression,
28
+ currentUser,
29
+ this.permissionService
30
+ );
31
+
32
+ if (!hasPermission) {
33
+ return res.status(403).json({ error: '禁止访问' });
34
+ }
35
+ }
36
+
37
+ next();
38
+ }
39
+
40
+ private getPermissionExpression(req: Request): string | null {
41
+ const route = req.route;
42
+ if (!route) {
43
+ return null;
44
+ }
45
+
46
+ const metadata = Reflect.getMetadata('aiko-boot:preAuthorize', route);
47
+ if (metadata) {
48
+ return metadata as string;
49
+ }
50
+
51
+ const rolesMetadata = Reflect.getMetadata('aiko-boot:roles', route);
52
+ if (rolesMetadata && Array.isArray(rolesMetadata)) {
53
+ const roles = rolesMetadata as string[];
54
+ if (roles.length > 0) {
55
+ return `hasAnyRole('${roles.join("','")}')`;
56
+ }
57
+ }
58
+
59
+ return null;
60
+ }
61
+ }
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "security-complete-example",
3
+ "version": "1.0.0",
4
+ "description": "Aiko Boot Starter Security 完整配置和集成示例",
5
+ "main": "app.ts",
6
+ "scripts": {
7
+ "start": "node --loader ts-node/esm app.ts",
8
+ "dev": "nodemon --exec node --loader ts-node/esm app.ts",
9
+ "build": "tsc",
10
+ "test": "pnpm jest",
11
+ "test:unit": "pnpm jest --config=tests/jest.config.js --testPathPattern=unit",
12
+ "test:integration": "pnpm jest --config=tests/jest.config.js --testPathPattern=integration",
13
+ "test:coverage": "pnpm jest --config=tests/jest.config.js --coverage",
14
+ "test:all": "node tests/run-all-tests.js",
15
+ "test:report": "node tests/generate-report.js",
16
+ "lint": "eslint . --ext .ts",
17
+ "format": "prettier --write \"**/*.ts\""
18
+ },
19
+ "dependencies": {
20
+ "@ai-partner-x/aiko-boot": "workspace:*",
21
+ "@ai-partner-x/aiko-boot-starter-security": "workspace:*",
22
+ "@ai-partner-x/aiko-boot-starter-orm": "workspace:*",
23
+ "@ai-partner-x/aiko-boot-starter-validation": "workspace:*",
24
+ "@ai-partner-x/aiko-boot-starter-web": "workspace:*",
25
+ "bcrypt": "^5.1.0",
26
+ "axios": "^1.6.0",
27
+ "express": "^4.18.2",
28
+ "express-session": "^1.17.3",
29
+ "better-sqlite3": "^9.2.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/bcrypt": "^5.0.0",
33
+ "@types/express": "^4.17.21",
34
+ "@types/express-session": "^1.17.10",
35
+ "@types/better-sqlite3": "^7.6.8",
36
+ "@types/node": "^20.10.0",
37
+ "@types/supertest": "^6.0.2",
38
+ "typescript": "^5.3.0",
39
+ "ts-node": "^10.9.2",
40
+ "nodemon": "^3.0.2",
41
+ "jest": "^29.7.0",
42
+ "@types/jest": "^29.5.11",
43
+ "ts-jest": "^29.1.1",
44
+ "supertest": "^6.3.3",
45
+ "eslint": "^8.55.0",
46
+ "@typescript-eslint/eslint-plugin": "^6.15.0",
47
+ "@typescript-eslint/parser": "^6.15.0",
48
+ "prettier": "^3.1.1"
49
+ },
50
+ "type": "module",
51
+ "engines": {
52
+ "node": ">=18.0.0"
53
+ }
54
+ }
@@ -0,0 +1,42 @@
1
+ -- 插入基础权限
2
+ INSERT INTO permissions (name, description, resource, action) VALUES
3
+ ('user:create', '创建用户', 'user', 'create'),
4
+ ('user:update', '更新用户', 'user', 'update'),
5
+ ('user:delete', '删除用户', 'user', 'delete'),
6
+ ('user:view', '查看用户', 'user', 'view'),
7
+ ('role:create', '创建角色', 'role', 'create'),
8
+ ('role:update', '更新角色', 'role', 'update'),
9
+ ('role:delete', '删除角色', 'role', 'delete'),
10
+ ('role:view', '查看角色', 'role', 'view'),
11
+ ('permission:create', '创建权限', 'permission', 'create'),
12
+ ('permission:update', '更新权限', 'permission', 'update'),
13
+ ('permission:delete', '删除权限', 'permission', 'delete'),
14
+ ('permission:view', '查看权限', 'permission', 'view');
15
+
16
+ -- 插入基础角色
17
+ INSERT INTO roles (name, description) VALUES
18
+ ('ADMIN', '管理员角色,拥有所有权限'),
19
+ ('USER', '普通用户角色'),
20
+ ('GUEST', '访客角色');
21
+
22
+ -- 为管理员角色分配所有权限
23
+ INSERT INTO role_permissions (roleId, permissionId)
24
+ SELECT 1, id FROM permissions;
25
+
26
+ -- 为普通用户角色分配部分权限
27
+ INSERT INTO role_permissions (roleId, permissionId)
28
+ SELECT 2, id FROM permissions WHERE name IN ('user:view', 'role:view', 'permission:view');
29
+
30
+ -- 创建管理员用户 (密码: Admin123!)
31
+ INSERT INTO users (username, email, password, enabled, provider, providerId, avatar)
32
+ VALUES ('admin', 'admin@example.com', '$2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy', 1, 'local', '', '');
33
+
34
+ -- 为管理员分配角色
35
+ INSERT INTO user_roles (userId, roleId) VALUES (1, 1);
36
+
37
+ -- 创建测试用户 (密码: User123!)
38
+ INSERT INTO users (username, email, password, enabled, provider, providerId, avatar)
39
+ VALUES ('user', 'user@example.com', '$2b$10$X7WfWfWfWfWfWfWfWfWfWeIjZAgcfl7p92ldGxad68LJZdL17lhWy', 1, 'local', '', '');
40
+
41
+ -- 为测试用户分配角色
42
+ INSERT INTO user_roles (userId, roleId) VALUES (2, 2);
@@ -0,0 +1,41 @@
1
+ import { Service, Autowired } from '@ai-partner-x/aiko-boot';
2
+ import { AuthService as SecurityAuthService } from '@ai-partner-x/aiko-boot-starter-security';
3
+ import { UserService } from './user.service.js';
4
+ import { OAuthService } from './oauth.service.js';
5
+ import type { RegisterDto } from '../dto/register.dto.js';
6
+
7
+ @Service()
8
+ export class AuthService {
9
+ @Autowired()
10
+ private securityAuthService!: SecurityAuthService;
11
+
12
+ @Autowired()
13
+ private userService!: UserService;
14
+
15
+ @Autowired()
16
+ private oauthService!: OAuthService;
17
+
18
+ async login(username: string, password: string) {
19
+ return this.securityAuthService.login({ username, password });
20
+ }
21
+
22
+ async register(userData: RegisterDto) {
23
+ return this.securityAuthService.register(userData);
24
+ }
25
+
26
+ async refreshToken(refreshToken: string) {
27
+ return this.securityAuthService.refreshToken(refreshToken);
28
+ }
29
+
30
+ async logout(token: string) {
31
+ return this.securityAuthService.logout(token);
32
+ }
33
+
34
+ async changePassword(userId: number, oldPassword: string, newPassword: string) {
35
+ return this.securityAuthService.changePassword(userId, oldPassword, newPassword);
36
+ }
37
+
38
+ async handleOAuthCallback(profile: any, tokens: any): Promise<any> {
39
+ return this.oauthService.handleOAuthCallback(profile, tokens);
40
+ }
41
+ }
@@ -0,0 +1,5 @@
1
+ export { AuthService } from './auth.service.js';
2
+ export { UserService } from './user.service.js';
3
+ export { RoleService } from './role.service.js';
4
+ export { PermissionService } from './permission.service.js';
5
+ export { OAuthService } from './oauth.service.js';
@@ -0,0 +1,82 @@
1
+ import { Service, Autowired } from '@ai-partner-x/aiko-boot';
2
+ import { Mapper, BaseMapper } from '@ai-partner-x/aiko-boot-starter-orm';
3
+ import { User } from '../entity/user.entity.js';
4
+ import { OAuthAccount } from '../entity/oauth-account.entity.js';
5
+ import type { OAuthProfileDto } from '../dto/oauth-profile.dto.js';
6
+
7
+ @Service()
8
+ export class OAuthService {
9
+ @Autowired()
10
+ private userMapper!: BaseMapper<User>;
11
+
12
+ @Autowired()
13
+ private oauthAccountMapper!: BaseMapper<OAuthAccount>;
14
+
15
+ async findOrCreateUser(profile: OAuthProfileDto): Promise<User> {
16
+ let user = await this.findByProvider(profile.provider, profile.providerId);
17
+
18
+ if (!user) {
19
+ user = await this.createUser(profile);
20
+ }
21
+
22
+ return user;
23
+ }
24
+
25
+ async findByProvider(provider: string, providerId: string): Promise<User | null> {
26
+ const accounts = await this.oauthAccountMapper.selectList({
27
+ where: { provider, providerId }
28
+ });
29
+
30
+ if (accounts.length === 0) {
31
+ return null;
32
+ }
33
+
34
+ const account = accounts[0];
35
+ return this.userMapper.selectById(account.userId);
36
+ }
37
+
38
+ async createUser(profile: OAuthProfileDto): Promise<User> {
39
+ const user = {
40
+ username: profile.username,
41
+ email: profile.email,
42
+ provider: profile.provider,
43
+ providerId: profile.providerId,
44
+ avatar: profile.avatar || '',
45
+ enabled: true,
46
+ createdAt: new Date(),
47
+ updatedAt: new Date(),
48
+ };
49
+
50
+ const userId = await this.userMapper.insert(user);
51
+ return this.userMapper.selectById(userId) as Promise<User>;
52
+ }
53
+
54
+ async saveOAuthAccount(userId: number, profile: OAuthProfileDto, tokens: any): Promise<void> {
55
+ const account = {
56
+ userId,
57
+ provider: profile.provider,
58
+ providerId: profile.providerId,
59
+ accessToken: tokens.access_token,
60
+ refreshToken: tokens.refresh_token || '',
61
+ expiresAt: tokens.expires_at ? new Date(tokens.expires_at * 1000) : new Date(Date.now() + 3600000),
62
+ createdAt: new Date(),
63
+ };
64
+
65
+ await this.oauthAccountMapper.insert(account);
66
+ }
67
+
68
+ async updateOAuthTokens(userId: number, provider: string, tokens: any): Promise<void> {
69
+ const accounts = await this.oauthAccountMapper.selectList({
70
+ where: { userId, provider }
71
+ });
72
+
73
+ if (accounts.length > 0) {
74
+ const account = accounts[0];
75
+ await this.oauthAccountMapper.updateById(account.id, {
76
+ accessToken: tokens.access_token,
77
+ refreshToken: tokens.refresh_token || account.refreshToken,
78
+ expiresAt: tokens.expires_at ? new Date(tokens.expires_at * 1000) : account.expiresAt,
79
+ });
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,113 @@
1
+ import { Service, Autowired } from '@ai-partner-x/aiko-boot';
2
+ import { Mapper, BaseMapper } from '@ai-partner-x/aiko-boot-starter-orm';
3
+ import { Permission } from '../entity/permission.entity.js';
4
+ import { Role } from '../entity/role.entity.js';
5
+ import { User } from '../entity/user.entity.js';
6
+ import { RolePermission } from '../entity/role-permission.entity.js';
7
+ import { UserRole } from '../entity/user-role.entity.js';
8
+
9
+ @Service()
10
+ export class PermissionService {
11
+ @Autowired()
12
+ private permissionMapper!: BaseMapper<Permission>;
13
+
14
+ @Autowired()
15
+ private roleMapper!: BaseMapper<Role>;
16
+
17
+ @Autowired()
18
+ private userMapper!: BaseMapper<User>;
19
+
20
+ @Autowired()
21
+ private rolePermissionMapper!: BaseMapper<RolePermission>;
22
+
23
+ @Autowired()
24
+ private userRoleMapper!: BaseMapper<UserRole>;
25
+
26
+ async getUserPermissions(userId: number): Promise<Permission[]> {
27
+ const user = await this.userMapper.selectById(userId);
28
+ if (!user) {
29
+ return [];
30
+ }
31
+
32
+ const userRoles = await this.userRoleMapper.selectList({
33
+ where: { userId }
34
+ });
35
+
36
+ const permissions: Permission[] = [];
37
+ for (const userRole of userRoles) {
38
+ const rolePermissions = await this.rolePermissionMapper.selectList({
39
+ where: { roleId: userRole.roleId }
40
+ });
41
+
42
+ for (const rp of rolePermissions) {
43
+ const permission = await this.permissionMapper.selectById(rp.permissionId);
44
+ if (permission && !permissions.find(p => p.id === permission.id)) {
45
+ permissions.push(permission);
46
+ }
47
+ }
48
+ }
49
+
50
+ return permissions;
51
+ }
52
+
53
+ async getRolePermissions(roleId: number): Promise<Permission[]> {
54
+ const rolePermissions = await this.rolePermissionMapper.selectList({
55
+ where: { roleId }
56
+ });
57
+
58
+ const permissions: Permission[] = [];
59
+ for (const rp of rolePermissions) {
60
+ const permission = await this.permissionMapper.selectById(rp.permissionId);
61
+ if (permission) {
62
+ permissions.push(permission);
63
+ }
64
+ }
65
+
66
+ return permissions;
67
+ }
68
+
69
+ async hasPermission(userId: number, permissionName: string): Promise<boolean> {
70
+ const permissions = await this.getUserPermissions(userId);
71
+ return permissions.some(p => p.name === permissionName);
72
+ }
73
+
74
+ async hasAnyPermission(userId: number, permissionNames: string[]): Promise<boolean> {
75
+ const permissions = await this.getUserPermissions(userId);
76
+ return permissionNames.some(name => permissions.some(p => p.name === name));
77
+ }
78
+
79
+ async hasAllPermissions(userId: number, permissionNames: string[]): Promise<boolean> {
80
+ const permissions = await this.getUserPermissions(userId);
81
+ return permissionNames.every(name => permissions.some(p => p.name === name));
82
+ }
83
+
84
+ async findById(id: number): Promise<Permission | null> {
85
+ return this.permissionMapper.selectById(id);
86
+ }
87
+
88
+ async findAll(): Promise<Permission[]> {
89
+ return this.permissionMapper.selectList({});
90
+ }
91
+
92
+ async create(permissionData: Partial<Permission>): Promise<Permission> {
93
+ const permission = {
94
+ ...permissionData,
95
+ createdAt: new Date(),
96
+ updatedAt: new Date(),
97
+ };
98
+ const id = await this.permissionMapper.insert(permission);
99
+ return this.permissionMapper.selectById(id) as Promise<Permission>;
100
+ }
101
+
102
+ async update(id: number, permissionData: Partial<Permission>): Promise<Permission> {
103
+ await this.permissionMapper.updateById(id, {
104
+ ...permissionData,
105
+ updatedAt: new Date(),
106
+ });
107
+ return this.permissionMapper.selectById(id) as Promise<Permission>;
108
+ }
109
+
110
+ async delete(id: number): Promise<boolean> {
111
+ return this.permissionMapper.deleteById(id) > 0;
112
+ }
113
+ }
@@ -0,0 +1,85 @@
1
+ import { Service, Autowired } from '@ai-partner-x/aiko-boot';
2
+ import { Mapper, BaseMapper } from '@ai-partner-x/aiko-boot-starter-orm';
3
+ import { Role } from '../entity/role.entity.js';
4
+ import { Permission } from '../entity/permission.entity.js';
5
+ import { RolePermission } from '../entity/role-permission.entity.js';
6
+ import { PermissionService } from './permission.service.js';
7
+
8
+ @Service()
9
+ export class RoleService {
10
+ @Autowired()
11
+ private roleMapper!: BaseMapper<Role>;
12
+
13
+ @Autowired()
14
+ private rolePermissionMapper!: BaseMapper<RolePermission>;
15
+
16
+ @Autowired()
17
+ private permissionService!: PermissionService;
18
+
19
+ async findById(id: number): Promise<Role | null> {
20
+ const role = await this.roleMapper.selectById(id);
21
+ if (!role) {
22
+ return null;
23
+ }
24
+
25
+ role.permissions = await this.permissionService.getRolePermissions(id);
26
+ return role;
27
+ }
28
+
29
+ async findAll(): Promise<Role[]> {
30
+ const roles = await this.roleMapper.selectList({});
31
+ for (const role of roles) {
32
+ role.permissions = await this.permissionService.getRolePermissions(role.id);
33
+ }
34
+ return roles;
35
+ }
36
+
37
+ async create(roleData: Partial<Role>): Promise<Role> {
38
+ const role = {
39
+ ...roleData,
40
+ createdAt: new Date(),
41
+ updatedAt: new Date(),
42
+ };
43
+ const id = await this.roleMapper.insert(role);
44
+ return this.roleMapper.selectById(id) as Promise<Role>;
45
+ }
46
+
47
+ async update(id: number, roleData: Partial<Role>): Promise<Role> {
48
+ await this.roleMapper.updateById(id, {
49
+ ...roleData,
50
+ updatedAt: new Date(),
51
+ });
52
+ return this.roleMapper.selectById(id) as Promise<Role>;
53
+ }
54
+
55
+ async delete(id: number): Promise<boolean> {
56
+ await this.rolePermissionMapper.selectList({
57
+ where: { roleId: id }
58
+ }).then(rolePermissions => {
59
+ for (const rp of rolePermissions) {
60
+ this.rolePermissionMapper.deleteById(rp.id);
61
+ }
62
+ });
63
+
64
+ return this.roleMapper.deleteById(id) > 0;
65
+ }
66
+
67
+ async assignPermissionToRole(roleId: number, permissionId: number): Promise<void> {
68
+ const rolePermission = {
69
+ roleId,
70
+ permissionId,
71
+ createdAt: new Date(),
72
+ };
73
+ await this.rolePermissionMapper.insert(rolePermission);
74
+ }
75
+
76
+ async removePermissionFromRole(roleId: number, permissionId: number): Promise<void> {
77
+ const rolePermissions = await this.rolePermissionMapper.selectList({
78
+ where: { roleId, permissionId }
79
+ });
80
+
81
+ for (const rp of rolePermissions) {
82
+ await this.rolePermissionMapper.deleteById(rp.id);
83
+ }
84
+ }
85
+ }