Skip to content

Dev#5871

Merged
KouShenhai merged 19 commits intomasterfrom
dev
Mar 15, 2026
Merged

Dev#5871
KouShenhai merged 19 commits intomasterfrom
dev

Conversation

@KouShenhai
Copy link
Owner

@KouShenhai KouShenhai commented Mar 15, 2026

Summary by Sourcery

引入带有验证码支持的自定义 Spring Security 登录页面,优化针对不同授权类型的认证验证码处理逻辑,并更新 UI/README 细节以匹配新的认证与许可模型。

新特性:

  • 新增专用的用户名/密码与 authorization-code 验证码 API,并将用户名/密码验证码获取流程集成到 Web 和前端的登录流程中。
  • 提供一个基于 Thymeleaf 的自定义登录页面,由新的 LoginController 和 Spring Security 表单登录配置提供支持。

缺陷修复:

  • 确保 authorization-code 认证可以使用验证码 key,而不是抛出不支持的操作错误。
  • 防止已通过认证且持有有效令牌的用户再次访问登录页面,并在前端进行退出导航时清理令牌。

增强改进:

  • 将 Auth 聚合与安全过滤器调整为 final,并增强 ID 生成器的空安全性。
  • 精简首页和登录页中的部分英文 UI 文案,并为登录表单字段启用输入清空和合理的默认值。
  • 调整网关/认证路由白名单以及资源服务器安全配置,以支持新的登录与验证码端点并改进 remember-me 行为。

构建:

  • 在认证服务中新增 Thymeleaf starter 依赖与配置,用于服务器端模板渲染。

文档:

  • 更新 README 中的组件版本、登录功能说明、许可条款为 Apache 2.0/MIT 双许可,并更新赞助表条目。
Original summary in English

Summary by Sourcery

Introduce a custom Spring Security login page with captcha support, refine authentication captcha handling for different grant types, and update UI/README details to match the new auth and licensing model.

New Features:

  • Add a dedicated username/password and authorization-code captcha API and integrate username/password captcha retrieval into the web and frontend login flows.
  • Provide a custom Thymeleaf-based login page backed by a new LoginController and Spring Security form login configuration.

Bug Fixes:

  • Ensure authorization-code authentication can use captcha keys instead of throwing an unsupported operation error.
  • Prevent already authenticated users with valid tokens from accessing the login page again and clear tokens on logout navigation in the frontend.

Enhancements:

  • Refine the Auth aggregate and security filters to be final and strengthen id generator null-safety.
  • Shorten some English UI copy on the home and login pages and enable input clearing and sensible defaults for login form fields.
  • Adjust gateway/auth route whitelists and resource server security settings for the new login and captcha endpoints and remember-me behavior.

Build:

  • Add Thymeleaf starter dependency and configuration for server-side templates in the auth service.

Documentation:

  • Update README component versions, login capability description, licensing terms to dual Apache 2.0/MIT, and sponsorship table entries.

Summary by CodeRabbit

  • New Features

    • Added authorization code login option alongside existing username/password login methods.
    • Introduced redesigned login page with improved user interface and form handling.
  • Documentation

    • Added MIT license file.
    • Updated project to dual-license under Apache 2.0 and MIT.
    • Updated dependency and version references throughout documentation.
  • Chores

    • Updated Spring Framework (7.0.5 → 7.0.6) and Spring Data (2025.1.3 → 2025.1.4) versions.
    • Added new sponsorship record.

@netlify
Copy link

netlify bot commented Mar 15, 2026

Deploy Preview for kcloud-platform-iot ready!

Name Link
🔨 Latest commit 28b8670
🔍 Latest deploy log https://app.netlify.com/projects/kcloud-platform-iot/deploys/69b673831bb1710008504a54
😎 Deploy Preview https://deploy-preview-5871--kcloud-platform-iot.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@sourcery-ai
Copy link

sourcery-ai bot commented Mar 15, 2026

Reviewer's Guide

实现了自定义的 Spring Security 登录流程,使用 Thymeleaf/Vue 登录页和按授权类型划分的验证码键/端点;更新了认证域行为以及验证码的 Redis key 使用方式;优化了安全配置和网关路由;改进前端登录体验(自动跳转、默认值、清空按钮、新验证码 API);并调整了文档和许可证配置。

用户名密码验证码生成与获取的时序图

sequenceDiagram
    actor Browser
    participant ReactLoginPage as ReactLoginPage
    participant Gateway as Gateway
    participant AuthService as AuthService
    participant CaptchasController as CaptchasController
    participant CaptchasServiceI as CaptchasServiceI
    participant CaptchaGetQryExe as CaptchaGetQryExe
    participant RedisUtils as RedisUtils

    Browser->>ReactLoginPage: Open SPA login page
    ReactLoginPage->>ReactLoginPage: uuidV7()
    ReactLoginPage->>Gateway: GET /apis/auth/api/v1/username-password/captchas/{uuid}
    Gateway->>AuthService: GET /v1/username-password/captchas/{uuid}

    AuthService->>CaptchasController: getUsernamePasswordAuthCaptchaByUuid(uuid)
    CaptchasController->>CaptchasServiceI: getCaptchaByUuid(CaptchaGetQry(key))
    CaptchasServiceI->>CaptchaGetQryExe: execute(CaptchaGetQry)
    CaptchaGetQryExe->>CaptchaGetQryExe: generate Captcha
    CaptchaGetQryExe->>RedisUtils: set(key,captcha,5min)
    RedisUtils-->>CaptchaGetQryExe: ok
    CaptchaGetQryExe-->>CaptchasServiceI: Result(base64)
    CaptchasServiceI-->>CaptchasController: Result(base64)
    CaptchasController-->>AuthService: Result(base64)
    AuthService-->>Gateway: Result(base64)
    Gateway-->>ReactLoginPage: Result(base64)
    ReactLoginPage->>Browser: Render captcha image
Loading

Spring Security 自定义登录页流程的时序图

sequenceDiagram
    actor User
    participant Browser
    participant Gateway as Gateway
    participant AuthService as AuthService
    participant LoginController as LoginController
    participant Thymeleaf as Thymeleaf
    participant SpringSecurity as SpringSecurity

    User->>Browser: Navigate to /login
    Browser->>Gateway: GET /api/login
    Gateway->>AuthService: GET /login

    AuthService->>LoginController: login()
    LoginController-->>Thymeleaf: View name login
    Thymeleaf-->>AuthService: Render login.html
    AuthService-->>Gateway: HTML login page
    Gateway-->>Browser: HTML login page

    User->>Browser: Fill form and submit
    Browser->>Gateway: POST /api/login (form data)
    Gateway->>AuthService: POST /login (form data)

    AuthService->>SpringSecurity: UsernamePasswordAuthenticationFilter
    SpringSecurity->>SpringSecurity: Authenticate
    SpringSecurity-->>AuthService: Success or failure
    AuthService-->>Gateway: Redirect to target or /login?error
    Gateway-->>Browser: Redirect response
Loading

更新后的认证验证码与登录组件类图

classDiagram
    class AuthA {
        <<final>>
        -Long serialVersionUID
        -IdGenerator authIdGenerator
        -HttpRequest httpRequest
        -PasswordValidator passwordValidator
        -CaptchaValidator captchaValidator
        -UserValidator userValidator
        -GrantType grantType
        -CaptchaV captchaV
        -UserV userV
        -SendCaptchaType sendCaptchaType
        +AuthA(authIdGenerator,httpRequest,passwordValidator,captchaValidator,userValidator,mobileCaptchaParamValidator)
        +AuthA createUsernamePasswordAuth()
        +AuthA createMobileAuth()
        +AuthA createMailAuth()
        +AuthA createAuthorizationCodeAuth()
        +AuthA createTestAuth()
        +AuthA createCaptchaVBySend(uuid,tag,tenantCode)
        -boolean isUseCaptcha()
        -String getCaptchaCacheKeyByAuth()
        -AuthA create()
    }

    class CaptchasController {
        -CaptchasServiceI captchasServiceI
        +Result getUsernamePasswordAuthCaptchaByUuid(uuid)
        +Result getAuthorizationCodeAuthCaptchaByUuid(uuid)
    }

    class CaptchaGetQry {
        -String key
        +CaptchaGetQry(key)
        +String getKey()
    }

    class CaptchaGetQryExe {
        -RedisUtils redisUtils
        +Result execute(CaptchaGetQry qry)
        -Captcha generate()
    }

    class RedisKeyUtils {
        +String getUsernamePasswordAuthCaptchaKey(uuid)
        +String getAuthorizationCodeAuthCaptchaKey(uuid)
    }

    class LoginController {
        +String login()
    }

    class I18nFilter {
        <<final>>
        +doFilterInternal(request,response,filterChain)
    }

    AuthA ..> IdGenerator
    AuthA ..> HttpRequest
    AuthA ..> PasswordValidator
    AuthA ..> CaptchaValidator
    AuthA ..> UserValidator

    CaptchasController --> CaptchasServiceI
    CaptchasServiceI --> CaptchaGetQryExe
    CaptchaGetQryExe --> RedisUtils

    CaptchasController ..> CaptchaGetQry
    RedisKeyUtils ..> CaptchasController

    LoginController <.. OAuth2ResourceServerConfig
Loading

文件级变更

Change Details Files
引入按授权类型划分的验证码 Redis key 和端点,并相应更新验证码生成逻辑。
  • 新增 RedisKeyUtils.getAuthorizationCodeAuthCaptchaKey,并使用基于 key 的 CaptchaGetQry,而不是只使用 UUID
  • 在 CaptchasController 和 gateway/auth 的 application.yml 白名单中,将验证码 REST 端点拆分为用户名密码和授权码两种变体
  • 修改 CaptchaGetQry 以存储通用 key,并更新 CaptchaGetQryExe 使用提供的 key 将验证码写入 Redis
  • 更新 UI 验证码服务和登录页,调用新的 /username-password/captchas/{uuid},替代旧的共享验证码端点
laokou-common/laokou-common-i18n/src/main/java/org/laokou/common/i18n/util/RedisKeyUtils.java
laokou-service/laokou-auth/laokou-auth-client/src/main/java/org/laokou/auth/dto/CaptchaGetQry.java
laokou-service/laokou-auth/laokou-auth-app/src/main/java/org/laokou/auth/command/query/CaptchaGetQryExe.java
laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/CaptchasController.java
laokou-service/laokou-auth/laokou-auth-start/src/main/resources/application.yml
laokou-cloud/laokou-gateway/src/main/resources/application.yml
ui/src/services/auth/captcha.ts
ui/src/pages/Login/index.tsx
增强 AuthA 聚合和验证码行为,以支持授权码验证码并改善对象创建语义。
  • 将 AuthA 声明为 final 类,并通过 @nonnull 要求 authIdGenerator 非空
  • 将内部的 init() 工厂方法重命名为 create(),并在所有 create*Auth 方法及 createCaptchaVBySend 中统一使用
  • 扩展 isUseCaptcha 和 getCaptchaCacheKeyByAuth 以支持 AUTHORIZATION_CODE 授权类型,并映射到新的 Redis 验证码 key
laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java
引入由 Spring MVC 控制器支撑的自定义 Thymeleaf+Vue 登录页,并调整 Spring Security 配置以使用该登录页。
  • 在 auth 基础设施配置中新增 spring-boot-starter-thymeleaf 依赖,并添加 Thymeleaf 属性(前缀、缓存、编码)
  • 新增 login.html 模板,实现带有 Vue/Element Plus 验证码处理、并在无 JS 时也能优雅降级的样式化登录表单
  • 新增 LoginController,提供 GET /login 并返回 login 视图
  • 在 OAuth2ResourceServerConfig 中自定义 formLogin,将 /login 同时作为 loginPage 和处理 URL,并禁用 rememberMe;在 application.yml 中将 /login 暴露为无需认证的路径
  • 在通用 OAuth2 资源服务器配置中同样禁用 rememberMe
laokou-service/laokou-auth/laokou-auth-infrastructure/pom.xml
laokou-service/laokou-auth/laokou-auth-start/src/main/resources/application.yml
laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html
laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/LoginController.java
laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2ResourceServerConfig.java
laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/config/OAuth2ResourceServerConfig.java
改进 React UI 中登录体验和 token 处理。
  • 在登录页中,将验证码 API 使用改为新的用户名密码端点,增加默认租户/用户名/密码值,在多个 ProForm 输入框上启用 allowClear,并在第三方登录区域添加安全图标
  • 组件挂载时,如果存在未过期 token,则将 /login 重定向到首页,并仅在 token 无效时初始化登录页;否则清理现有 token 并加载公钥/验证码
  • 登出时,确保在重定向到 /login 前调用 clearToken()
  • 缩短部分英文 i18n 文案,并将登录标签从“User pwd login”调整为“Password login”
ui/src/pages/Login/index.tsx
ui/src/app.tsx
ui/src/locales/en-US.ts
在安全/授权组件中收紧不可变性并统一格式。
  • 将 I18nFilter 和 AuthA 标记为 final 类
  • 微调 OAuth2AuthorizationServerConfig 中 bean 方法签名(authRedisSegmentIdGenerator 和 authIdGenerator),但不改变其行为
  • 在共享的 OAuth2 资源服务器配置中添加 rememberMe(AbstractHttpConfigurer::disable)
  • 对 access.ts 中的权限映射进行格式化微调(空格与空行)
laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/filter/I18nFilter.java
laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2AuthorizationServerConfig.java
ui/src/access.ts
laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/config/OAuth2ResourceServerConfig.java
更新文档、许可证和声明,以反映新版本和授权模式。
  • 在 README 徽章和组件表中提升 Spring Framework 和 Spring Data 版本,并将登录功能描述调整为提到授权码登录
  • 更新某个 image 标签的 height 属性(新的语法似乎有问题,需要再次确认)
  • 在用户权益部分改为描述 Apache2.0/MIT 双许可证,移除旧的详细再授权表,并在修订后的许可证章节下新增明确的 Apache 和 MIT 授权条目,同时添加关于通过购买移除版权的说明
  • 在捐赠表中新增一条赞助条目
  • 新增 MIT 许可证文件和 MIT checkstyle 头文件;并修改 NOTICE、README.adoc 和归档文档路径
README.md
NOTICE
README.adoc
LICENSE-MIT
checkstyle/checkstyle-mit-header.txt
b/archive/docs/01.基础/00.基础.md

Tips and commands

与 Sourcery 交互

  • 触发新评审: 在 Pull Request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的评审评论。
  • 从评审评论生成 GitHub Issue: 在评审评论下回复,要求 Sourcery 从该评论创建 issue。也可以直接回复 @sourcery-ai issue,从该评论生成 issue。
  • 生成 Pull Request 标题: 在 Pull Request 标题中任意位置写上 @sourcery-ai,即可随时生成标题。也可以在 Pull Request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 Pull Request 摘要: 在 Pull Request 正文任意位置写上 @sourcery-ai summary,即可在该位置生成 PR 摘要。也可以在 Pull Request 中评论 @sourcery-ai summary 来(重新)生成摘要。
  • 生成评审指南: 在 Pull Request 中评论 @sourcery-ai guide,可以随时(重新)生成评审指南。
  • 解决所有 Sourcery 评论: 在 Pull Request 中评论 @sourcery-ai resolve,可一次性标记解决所有 Sourcery 评论。如果你已经处理了所有评论且不希望再看到它们,这会非常有用。
  • 忽略所有 Sourcery 评审: 在 Pull Request 中评论 @sourcery-ai dismiss,可忽略所有现有 Sourcery 评审。尤其适用于你希望从一次全新的评审开始——记得随后评论 @sourcery-ai review 触发新评审!

自定义你的使用体验

访问你的 控制面板 以:

  • 启用或禁用评审功能,例如 Sourcery 自动生成的 Pull Request 摘要、评审指南等。
  • 更改评审语言。
  • 添加、移除或编辑自定义评审指令。
  • 调整其他评审设置。

获取帮助

Original review guide in English

Reviewer's Guide

Implements a customized Spring Security login flow with a Thymeleaf/Vue login page and per-grant-type captcha keys/endpoints, updates auth domain behavior and redis key usage for captchas, refines security configs and gateway routes, improves front-end login UX (auto-redirect, default values, clear buttons, new captcha API), and adjusts documentation and licensing.

Sequence diagram for username-password captcha generation and retrieval

sequenceDiagram
    actor Browser
    participant ReactLoginPage as ReactLoginPage
    participant Gateway as Gateway
    participant AuthService as AuthService
    participant CaptchasController as CaptchasController
    participant CaptchasServiceI as CaptchasServiceI
    participant CaptchaGetQryExe as CaptchaGetQryExe
    participant RedisUtils as RedisUtils

    Browser->>ReactLoginPage: Open SPA login page
    ReactLoginPage->>ReactLoginPage: uuidV7()
    ReactLoginPage->>Gateway: GET /apis/auth/api/v1/username-password/captchas/{uuid}
    Gateway->>AuthService: GET /v1/username-password/captchas/{uuid}

    AuthService->>CaptchasController: getUsernamePasswordAuthCaptchaByUuid(uuid)
    CaptchasController->>CaptchasServiceI: getCaptchaByUuid(CaptchaGetQry(key))
    CaptchasServiceI->>CaptchaGetQryExe: execute(CaptchaGetQry)
    CaptchaGetQryExe->>CaptchaGetQryExe: generate Captcha
    CaptchaGetQryExe->>RedisUtils: set(key,captcha,5min)
    RedisUtils-->>CaptchaGetQryExe: ok
    CaptchaGetQryExe-->>CaptchasServiceI: Result(base64)
    CaptchasServiceI-->>CaptchasController: Result(base64)
    CaptchasController-->>AuthService: Result(base64)
    AuthService-->>Gateway: Result(base64)
    Gateway-->>ReactLoginPage: Result(base64)
    ReactLoginPage->>Browser: Render captcha image
Loading

Sequence diagram for Spring Security custom login page flow

sequenceDiagram
    actor User
    participant Browser
    participant Gateway as Gateway
    participant AuthService as AuthService
    participant LoginController as LoginController
    participant Thymeleaf as Thymeleaf
    participant SpringSecurity as SpringSecurity

    User->>Browser: Navigate to /login
    Browser->>Gateway: GET /api/login
    Gateway->>AuthService: GET /login

    AuthService->>LoginController: login()
    LoginController-->>Thymeleaf: View name login
    Thymeleaf-->>AuthService: Render login.html
    AuthService-->>Gateway: HTML login page
    Gateway-->>Browser: HTML login page

    User->>Browser: Fill form and submit
    Browser->>Gateway: POST /api/login (form data)
    Gateway->>AuthService: POST /login (form data)

    AuthService->>SpringSecurity: UsernamePasswordAuthenticationFilter
    SpringSecurity->>SpringSecurity: Authenticate
    SpringSecurity-->>AuthService: Success or failure
    AuthService-->>Gateway: Redirect to target or /login?error
    Gateway-->>Browser: Redirect response
Loading

Class diagram for updated auth captcha and login components

classDiagram
    class AuthA {
        <<final>>
        -Long serialVersionUID
        -IdGenerator authIdGenerator
        -HttpRequest httpRequest
        -PasswordValidator passwordValidator
        -CaptchaValidator captchaValidator
        -UserValidator userValidator
        -GrantType grantType
        -CaptchaV captchaV
        -UserV userV
        -SendCaptchaType sendCaptchaType
        +AuthA(authIdGenerator,httpRequest,passwordValidator,captchaValidator,userValidator,mobileCaptchaParamValidator)
        +AuthA createUsernamePasswordAuth()
        +AuthA createMobileAuth()
        +AuthA createMailAuth()
        +AuthA createAuthorizationCodeAuth()
        +AuthA createTestAuth()
        +AuthA createCaptchaVBySend(uuid,tag,tenantCode)
        -boolean isUseCaptcha()
        -String getCaptchaCacheKeyByAuth()
        -AuthA create()
    }

    class CaptchasController {
        -CaptchasServiceI captchasServiceI
        +Result getUsernamePasswordAuthCaptchaByUuid(uuid)
        +Result getAuthorizationCodeAuthCaptchaByUuid(uuid)
    }

    class CaptchaGetQry {
        -String key
        +CaptchaGetQry(key)
        +String getKey()
    }

    class CaptchaGetQryExe {
        -RedisUtils redisUtils
        +Result execute(CaptchaGetQry qry)
        -Captcha generate()
    }

    class RedisKeyUtils {
        +String getUsernamePasswordAuthCaptchaKey(uuid)
        +String getAuthorizationCodeAuthCaptchaKey(uuid)
    }

    class LoginController {
        +String login()
    }

    class I18nFilter {
        <<final>>
        +doFilterInternal(request,response,filterChain)
    }

    AuthA ..> IdGenerator
    AuthA ..> HttpRequest
    AuthA ..> PasswordValidator
    AuthA ..> CaptchaValidator
    AuthA ..> UserValidator

    CaptchasController --> CaptchasServiceI
    CaptchasServiceI --> CaptchaGetQryExe
    CaptchaGetQryExe --> RedisUtils

    CaptchasController ..> CaptchaGetQry
    RedisKeyUtils ..> CaptchasController

    LoginController <.. OAuth2ResourceServerConfig
Loading

File-Level Changes

Change Details Files
Introduce grant-type specific captcha keys and endpoints and update captcha generation logic accordingly.
  • Add RedisKeyUtils.getAuthorizationCodeAuthCaptchaKey and use key-based CaptchaGetQry instead of UUID-only
  • Split captcha REST endpoints into username-password and authorization-code variants in CaptchasController and gateway/auth application.yml whitelists
  • Modify CaptchaGetQry to store a generic key and update CaptchaGetQryExe to write captcha values to Redis using the provided key
  • Update UI captcha service and login page to call /username-password/captchas/{uuid} instead of the old shared captcha endpoint
laokou-common/laokou-common-i18n/src/main/java/org/laokou/common/i18n/util/RedisKeyUtils.java
laokou-service/laokou-auth/laokou-auth-client/src/main/java/org/laokou/auth/dto/CaptchaGetQry.java
laokou-service/laokou-auth/laokou-auth-app/src/main/java/org/laokou/auth/command/query/CaptchaGetQryExe.java
laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/CaptchasController.java
laokou-service/laokou-auth/laokou-auth-start/src/main/resources/application.yml
laokou-cloud/laokou-gateway/src/main/resources/application.yml
ui/src/services/auth/captcha.ts
ui/src/pages/Login/index.tsx
Enhance AuthA aggregate and captcha behavior to support authorization-code captcha and improve object creation semantics.
  • Make AuthA final and require a non-null authIdGenerator via @nonnull
  • Rename internal init() factory method to create() and use it consistently from create*Auth methods and createCaptchaVBySend
  • Extend isUseCaptcha and getCaptchaCacheKeyByAuth to support AUTHORIZATION_CODE grant type, mapping to the new redis captcha key
laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java
Introduce a custom Thymeleaf+Vue login page backed by a Spring MVC controller and align Spring Security config to use it.
  • Add spring-boot-starter-thymeleaf dependency and Thymeleaf properties (prefix, cache, encoding) in auth infrastructure configuration
  • Add login.html template implementing a styled login form with Vue/Element Plus captcha handling and graceful no-JS fallback
  • Add LoginController serving GET /login to return the login view
  • Customize OAuth2ResourceServerConfig formLogin to use /login as both loginPage and processing URL and disable rememberMe; expose /login as unauthenticated in application.yml
  • Disable rememberMe in common OAuth2 resource server configuration as well
laokou-service/laokou-auth/laokou-auth-infrastructure/pom.xml
laokou-service/laokou-auth/laokou-auth-start/src/main/resources/application.yml
laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html
laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/LoginController.java
laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2ResourceServerConfig.java
laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/config/OAuth2ResourceServerConfig.java
Improve front-end login UX and token handling in the React UI.
  • In Login page, change captcha API usage to the new username-password endpoint, add default tenant/username/password values, enable allowClear on multiple ProForm inputs, and add a security icon to the third-party login section
  • On mount, if a non-expired token exists, redirect /login to home and only initialize login page when token is invalid; otherwise clear existing tokens and load public key/captcha
  • On logout, ensure clearToken() is called before redirecting to /login
  • Shorten some English i18n texts and adjust login tab label from 'User pwd login' to 'Password login'
ui/src/pages/Login/index.tsx
ui/src/app.tsx
ui/src/locales/en-US.ts
Tighten immutability and formatting across security/authorization components.
  • Mark I18nFilter and AuthA as final classes
  • Refine bean method signatures in OAuth2AuthorizationServerConfig (authRedisSegmentIdGenerator and authIdGenerator) without changing behavior
  • Add rememberMe(AbstractHttpConfigurer::disable) in shared OAuth2 resource server config
  • Apply formatting tweaks in access.ts permission map (spacing and blank lines)
laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/filter/I18nFilter.java
laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2AuthorizationServerConfig.java
ui/src/access.ts
laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/config/OAuth2ResourceServerConfig.java
Update documentation, licensing, and notices to reflect new versions and license model.
  • Bump Spring Framework and Spring Data versions in README badges and component table, adjust login feature description to mention authorization-code login
  • Update an image tag height attribute (though the new syntax appears malformed and should be double-checked)
  • Change user-rights section to describe dual Apache2.0/MIT license, remove old detailed re-licensing table, and add explicit Apache and MIT license bullets under a revised license section with a note about removing copyright via purchase
  • Add new sponsorship entry to the donation table
  • Add MIT license file and MIT checkstyle header file; touch NOTICE, README.adoc, and archived doc paths
README.md
NOTICE
README.adoc
LICENSE-MIT
checkstyle/checkstyle-mit-header.txt
b/archive/docs/01.基础/00.基础.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@KouShenhai KouShenhai merged commit f85141f into master Mar 15, 2026
9 of 15 checks passed
@coderabbitai
Copy link

coderabbitai bot commented Mar 15, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a373fffe-246e-4c8c-963d-c15aaf16f3d9

📥 Commits

Reviewing files that changed from the base of the PR and between 77e4324 and 28b8670.

⛔ Files ignored due to path filters (1)
  • ui/public/FfdJeJRQWjEeGTpqgBKj.png is excluded by !**/*.png
📒 Files selected for processing (25)
  • LICENSE-MIT
  • NOTICE
  • README.adoc
  • README.md
  • archive/docs/01.赞助/00.赞助.md
  • checkstyle/checkstyle-mit-header.txt
  • laokou-cloud/laokou-gateway/src/main/resources/application.yml
  • laokou-common/laokou-common-i18n/src/main/java/org/laokou/common/i18n/util/RedisKeyUtils.java
  • laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/config/OAuth2ResourceServerConfig.java
  • laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/filter/I18nFilter.java
  • laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/CaptchasController.java
  • laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/LoginController.java
  • laokou-service/laokou-auth/laokou-auth-app/src/main/java/org/laokou/auth/command/query/CaptchaGetQryExe.java
  • laokou-service/laokou-auth/laokou-auth-client/src/main/java/org/laokou/auth/dto/CaptchaGetQry.java
  • laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java
  • laokou-service/laokou-auth/laokou-auth-infrastructure/pom.xml
  • laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2AuthorizationServerConfig.java
  • laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2ResourceServerConfig.java
  • laokou-service/laokou-auth/laokou-auth-start/src/main/resources/application.yml
  • laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html
  • ui/src/access.ts
  • ui/src/app.tsx
  • ui/src/locales/en-US.ts
  • ui/src/pages/Login/index.tsx
  • ui/src/services/auth/captcha.ts

Walkthrough

This PR implements dual licensing (Apache 2.0 and MIT), introduces authorization code OAuth2 grant type support with separate captcha endpoints, adds a Thymeleaf-based login page template with Vue3 frontend integration, refactors authentication domain logic, and enhances permission flags and frontend capabilities across the application.

Changes

Cohort / File(s) Summary
Licensing & Documentation
LICENSE-MIT, NOTICE, README.adoc, README.md, archive/docs/.../赞助.md
Added MIT license file, dual-license notices (Apache 2.0 and MIT), updated framework versions (Spring 7.0.6, Spring Data 2025.1.4), expanded feature descriptions, added new sponsorship entry dated 2026-03-11.
Authorization Code Grant Type Support
laokou-common/laokou-common-i18n/.../RedisKeyUtils.java, laokou-service/.../CaptchasController.java, laokou-service/.../CaptchaGetQry.java, laokou-service/.../CaptchaGetQryExe.java, laokou-service/.../AuthA.java
Introduced new authorization code flow with dedicated captcha endpoints (/v1/authorization-code/captchas/{uuid} and /v1/username-password/captchas/{uuid}), added Redis key generator for authorization code captchas, refactored captcha query to use generic key parameter, extended AuthA domain model to support AUTHORIZATION_CODE grant type.
Login Page & Controller
laokou-service/.../LoginController.java, laokou-service/.../templates/login.html
Added new LoginController serving GET /login, created comprehensive login template with Thymeleaf/Vue3 integration supporting captcha refresh, error display, and dual-column responsive UI.
Thymeleaf Configuration & Dependencies
laokou-service/.../pom.xml, laokou-service/.../application.yml (start)
Added spring-boot-starter-thymeleaf dependency, configured Thymeleaf settings (caching, encoding, template location).
API Gateway & Security Configuration
laokou-cloud/.../application.yml (gateway), laokou-service/.../OAuth2ResourceServerConfig.java, laokou-common/.../OAuth2ResourceServerConfig.java
Updated gateway ignore patterns for new captcha endpoints and /login route, configured custom form login with /login page and processing URL, disabled remember-me functionality.
OAuth2 Bean Visibility & Server Config
laokou-service/.../OAuth2AuthorizationServerConfig.java
Reduced visibility of authRedisSegmentIdGenerator and authIdGenerator beans from public to package-private.
Code Quality Improvements
laokou-common/.../I18nFilter.java, laokou-service/.../AuthA.java
Made I18nFilter and AuthA classes final, added @NonNull annotation to constructor parameters, renamed private init() method to create() throughout AuthA.
Checkstyle Configuration
checkstyle/checkstyle-mit-header.txt
Added MIT license header validation configuration for checkstyle.
Frontend Permissions & Access Control
ui/src/access.ts
Added 30+ new permission flags covering detail/modify/remove/save operations for resources (Menu, Dept, Role, User, Oss, Device, Product, ThingModel, ProductCategory, OperateLog, NoticeLog, LoginLog) with scope-based gating.
Frontend Login & Authentication
ui/src/pages/Login/index.tsx, ui/src/services/auth/captcha.ts, ui/src/app.tsx, ui/src/locales/en-US.ts
Updated captcha API to use getUsernamePasswordAuthCaptchaByUuid, added login flow control with token expiration checks, enhanced form fields with clear buttons and default values, added token clearance to logout flow, updated English translations.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client/Browser
    participant Controller as CaptchasController
    participant RedisKeyUtils as RedisKeyUtils
    participant Redis as Redis Cache
    
    Client->>Controller: GET /v1/authorization-code/captchas/{uuid}
    Controller->>RedisKeyUtils: getAuthorizationCodeAuthCaptchaKey(uuid)
    RedisKeyUtils-->>Controller: "auth:authorization-code:captcha:{uuid}"
    Controller->>Redis: GET auth:authorization-code:captcha:{uuid}
    Redis-->>Controller: captcha data (or null)
    Controller-->>Client: Result<String> with captcha
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

Review effort 4/5, Feature: Authorization Code, Backend, Frontend, Licensing


🐰 A dual license blooms so fine,
Authorization codes intertwine,
Login pages with Vue's delight,
Captchas split in morning light,
Thymeleaf templates take flight! 🌟

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev
📝 Coding Plan
  • Generate coding plan for human review comments

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 OpenGrep (1.16.4)
laokou-common/laokou-common-i18n/src/main/java/org/laokou/common/i18n/util/RedisKeyUtils.java

┌──────────────┐
│ Opengrep CLI │
└──────────────┘

�[32m✔�[39m �[1mOpengrep OSS�[0m
�[32m✔�[39m Basic security coverage for first-party code vulnerabilities.

�[1m Loading rules from local config...�[0m

laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/config/OAuth2ResourceServerConfig.java

┌──────────────┐
│ Opengrep CLI │
└──────────────┘

�[32m✔�[39m �[1mOpengrep OSS�[0m
�[32m✔�[39m Basic security coverage for first-party code vulnerabilities.

�[1m Loading rules from local config...�[0m

laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/filter/I18nFilter.java

┌──────────────┐
│ Opengrep CLI │
└──────────────┘

�[32m✔�[39m �[1mOpengrep OSS�[0m
�[32m✔�[39m Basic security coverage for first-party code vulnerabilities.

�[1m Loading rules from local config...�[0m

  • 12 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can use TruffleHog to scan for secrets in your code with verification capabilities.

Add a TruffleHog config file (e.g. trufflehog-config.yml, trufflehog.yml) to your project to customize detectors and scanning behavior. The tool runs only when a config file is present.

@qodo-code-review
Copy link

Review Summary by Qodo

Add authorization code auth, custom login page, and dual licensing

✨ Enhancement 📝 Documentation

Grey Divider

Walkthroughs

Description
• Add authorization code authentication with dedicated captcha endpoint
• Implement custom login page with Thymeleaf and Vue3 UI
• Refactor captcha endpoints to support multiple auth types
• Update dual licensing to Apache 2.0 and MIT
• Add default credentials and improve login form UX
Diagram
flowchart LR
  A["Auth System"] -->|"Add captcha key"| B["RedisKeyUtils"]
  A -->|"New endpoint"| C["Authorization Code Captcha"]
  A -->|"Refactor"| D["Username/Password Captcha"]
  E["LoginController"] -->|"Render"| F["login.html Template"]
  F -->|"Vue3 + Element Plus"| G["Custom Login UI"]
  H["Licensing"] -->|"Add MIT"| I["Dual License"]
  I -->|"Keep Apache 2.0"| J["License Files"]
Loading

Grey Divider

File Changes

1. laokou-common/laokou-common-i18n/src/main/java/org/laokou/common/i18n/util/RedisKeyUtils.java ✨ Enhancement +8/-0

Add authorization code captcha Redis key utility

laokou-common/laokou-common-i18n/src/main/java/org/laokou/common/i18n/util/RedisKeyUtils.java


2. laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/config/OAuth2ResourceServerConfig.java ✨ Enhancement +1/-0

Disable remember-me in resource server security config

laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/config/OAuth2ResourceServerConfig.java


3. laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/filter/I18nFilter.java ✨ Enhancement +1/-1

Make I18nFilter class final for immutability

laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/filter/I18nFilter.java


View more (22)
4. laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/CaptchasController.java ✨ Enhancement +16/-5

Split captcha endpoints for username-password and authorization-code

laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/CaptchasController.java


5. laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/LoginController.java ✨ Enhancement +34/-0

Create new login controller with custom login page endpoint

laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/LoginController.java


6. laokou-service/laokou-auth/laokou-auth-app/src/main/java/org/laokou/auth/command/query/CaptchaGetQryExe.java ✨ Enhancement +1/-4

Refactor to use generic key parameter instead of UUID

laokou-service/laokou-auth/laokou-auth-app/src/main/java/org/laokou/auth/command/query/CaptchaGetQryExe.java


7. laokou-service/laokou-auth/laokou-auth-client/src/main/java/org/laokou/auth/dto/CaptchaGetQry.java ✨ Enhancement +2/-2

Change uuid field to generic key parameter

laokou-service/laokou-auth/laokou-auth-client/src/main/java/org/laokou/auth/dto/CaptchaGetQry.java


8. laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java ✨ Enhancement +13/-11

Add authorization code to captcha validation and refactor init method

laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java


9. laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2AuthorizationServerConfig.java ✨ Enhancement +2/-3

Remove public modifiers from bean method declarations

laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2AuthorizationServerConfig.java


10. laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2ResourceServerConfig.java ✨ Enhancement +8/-7

Configure custom login page with form login and disable remember-me

laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2ResourceServerConfig.java


11. ui/src/access.ts Formatting +30/-0

Add blank lines for code formatting consistency

ui/src/access.ts


12. ui/src/locales/en-US.ts 📝 Documentation +3/-3

Update English translations for device messages and login

ui/src/locales/en-US.ts


13. ui/src/services/auth/captcha.ts ✨ Enhancement +2/-2

Rename and update captcha API endpoint for username-password auth

ui/src/services/auth/captcha.ts


14. laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html ✨ Enhancement +344/-0

Create custom login page with Thymeleaf and Vue3 UI

laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html


15. LICENSE-MIT 📝 Documentation +21/-0

Add MIT license file for dual licensing

LICENSE-MIT


16. NOTICE 📝 Documentation +30/-0

Add dual licensing notice for Apache 2.0 and MIT

NOTICE


17. README.adoc 📝 Documentation +12/-18

Update Spring Framework version and dual licensing information

README.adoc


18. README.md 📝 Documentation +12/-17

Update Spring Framework version and dual licensing information

README.md


19. archive/docs/01.赞助/00.赞助.md 📝 Documentation +1/-0

Add new sponsor entry to sponsorship list

archive/docs/01.赞助/00.赞助.md


20. checkstyle/checkstyle-mit-header.txt ⚙️ Configuration changes +15/-0

Add MIT license header template for checkstyle validation

checkstyle/checkstyle-mit-header.txt


21. laokou-cloud/laokou-gateway/src/main/resources/application.yml ⚙️ Configuration changes +3/-1

Update captcha endpoints and add login route to gateway config

laokou-cloud/laokou-gateway/src/main/resources/application.yml


22. laokou-service/laokou-auth/laokou-auth-infrastructure/pom.xml Dependencies +4/-0

Add Thymeleaf dependency for template rendering

laokou-service/laokou-auth/laokou-auth-infrastructure/pom.xml


23. laokou-service/laokou-auth/laokou-auth-start/src/main/resources/application.yml ⚙️ Configuration changes +9/-1

Configure Thymeleaf and update captcha endpoint patterns

laokou-service/laokou-auth/laokou-auth-start/src/main/resources/application.yml


24. ui/src/app.tsx 🐞 Bug fix +1/-0

Clear token on logout before redirecting to login

ui/src/app.tsx


25. ui/src/pages/Login/index.tsx ✨ Enhancement +39/-3

Add default credentials, authorization code UI, and token expiry check

ui/src/pages/Login/index.tsx


Grey Divider

Qodo Logo

@qodo-code-review
Copy link

qodo-code-review bot commented Mar 15, 2026

Code Review by Qodo

🐞 Bugs (6) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Auth-code captcha null 🐞 Bug ✓ Correctness
Description
AuthA now requires captcha for AUTHORIZATION_CODE but createAuthorizationCodeAuth() never
initializes captchaV, so DomainService.auth() will hit a NullPointerException in checkCaptcha() when
captchaV is dereferenced.
Code

laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[R384-388]

+		return List.of(GrantType.USERNAME_PASSWORD, GrantType.MOBILE, GrantType.MAIL, GrantType.AUTHORIZATION_CODE)
+			.contains(grantType);
	}

	private boolean isUsePassword() {
Evidence
createAuthorizationCodeAuth() sets only grantType and userV, but isUseCaptcha() includes
AUTHORIZATION_CODE and checkCaptcha() dereferences captchaV (captchaV.captcha() and
captchaV.uuid()). Since DomainService.auth() always calls checkCaptcha(), authorization-code auth
will NPE before user validation.

laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[220-224]
laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[323-333]
laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[383-400]
laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/ability/DomainService.java[63-72]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
AUTHORIZATION_CODE auth now goes through captcha validation, but `AuthA.createAuthorizationCodeAuth()` never sets `captchaV`. This makes `AuthA.checkCaptcha()` dereference `captchaV` and crash with a NullPointerException.

## Issue Context
- `DomainService.auth()` always invokes `authA.checkCaptcha()`.
- `isUseCaptcha()` includes `GrantType.AUTHORIZATION_CODE`.
- `checkCaptcha()` reads `this.captchaV.captcha()` and `getCaptchaCacheKeyByAuth()` reads `this.captchaV.uuid()`.

## Fix Focus Areas
- laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[220-224]
- laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[323-333]
- laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[383-400]
- laokou-service/laokou-auth/laokou-auth-app/src/main/java/org/laokou/auth/service/validator/AuthorizationCodeAuthParamValidator.java[37-47]

## Suggested approach
1. Add a method like `getCaptchaVByAuthorizationCodeAuth()` (similar to username-password) that reads `uuid` and `captcha` parameters.
2. In `createAuthorizationCodeAuth()`, set `this.captchaV = getCaptchaVByAuthorizationCodeAuth()`.
3. Update `AuthorizationCodeAuthParamValidator` to validate the captcha-related parameters if captcha is required for this grant type.
4. Alternatively (if captcha is not intended for AUTHORIZATION_CODE), remove it from `isUseCaptcha()` and from `getCaptchaCacheKeyByAuth()`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Gateway login path mismatch 🐞 Bug ⛯ Reliability
Description
Gateway unauthenticated allowlist includes GET /api/login but the auth server exposes the login page
at /login, so accessing /login through the gateway will not match the allowlist and will be blocked
by AuthFilter as Unauthorized.
Code

laokou-cloud/laokou-gateway/src/main/resources/application.yml[R196-202]

+      - /api/v1/username-password/captchas/{uuid}=laokou-gateway
+      - /api/v1/authorization-code/captchas/{uuid}=laokou-gateway
      - /api/v1/secrets=laokou-gateway
      - /doc.html=laokou-gateway
      - /webjars/**=laokou-gateway
      - /ws=laokou-gateway
+      - /api/login=laokou-gateway
Evidence
Gateway AuthFilter permits requests only when they match request-matcher.ignore-patterns; the config
added /api/login but the auth service login endpoint is /login (and Spring Security is
configured to use /login). Therefore /login requests won’t be permitted by the gateway
allowlist.

laokou-cloud/laokou-gateway/src/main/java/org/laokou/gateway/filter/AuthFilter.java[74-83]
laokou-cloud/laokou-gateway/src/main/resources/application.yml[190-206]
laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/LoginController.java[29-32]
laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2ResourceServerConfig.java[67-71]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Gateway allowlist permits `GET /api/login`, but the auth service login page is `GET /login` and Spring Security processes `POST /login`. Gateway `AuthFilter` blocks any request not in the allowlist when no Authorization header is present, making the login page unreachable through the gateway.

## Issue Context
- Gateway relies on `request-matcher.ignore-patterns` to bypass auth.
- Auth service uses `/login` for login page and login processing.

## Fix Focus Areas
- laokou-cloud/laokou-gateway/src/main/resources/application.yml[190-206]
- laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/LoginController.java[29-32]
- laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2ResourceServerConfig.java[67-71]

## Suggested approach
1. Add `GET /login=laokou-gateway` and `POST /login=laokou-gateway` to the gateway ignore-patterns.
2. Remove or repurpose `/api/login` unless a real route exists.
3. If the intended public endpoint is `/api/login`, change the auth controller + Spring Security loginPage/loginProcessingUrl to `/api/login` and ensure templates resolve correctly.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Standalone captcha whitelist stale 🐞 Bug ⛯ Reliability
Description
Standalone auth resource-server ignore-patterns still whitelist only /v1/captchas/{uuid}, so the new
captcha endpoints won’t be publicly accessible in standalone mode and login flows that need captcha
will be blocked.
Code

laokou-service/laokou-auth/laokou-auth-start/src/main/resources/application.yml[R160-165]

+              - /v1/username-password/captchas/{uuid}=laokou-auth
+              - /v1/authorization-code/captchas/{uuid}=laokou-auth
              - /v1/secrets=laokou-auth
              - /doc.html=laokou-auth
              - /webjars/**=laokou-auth
+              - /login=laokou-auth
Evidence
The main auth service configuration was updated to whitelist the new captcha endpoints, but the
standalone-auth-start configuration still references the removed /v1/captchas/{uuid} path, leaving
the new endpoints protected (requiring authentication) in standalone deployments.

laokou-service/laokou-auth/laokou-auth-start/src/main/resources/application.yml[160-165]
laokou-service/laokou-standalone/laokou-standalone-auth/laokou-standalone-auth-start/src/main/resources/application.yml[150-160]
laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/CaptchasController.java[50-65]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Standalone auth configuration still whitelists the removed captcha endpoint `/v1/captchas/{uuid}` and does not whitelist the new captcha endpoints. This blocks captcha retrieval pre-auth in standalone deployments.

## Issue Context
Auth service has migrated to:
- `/v1/username-password/captchas/{uuid}`
- `/v1/authorization-code/captchas/{uuid}`

## Fix Focus Areas
- laokou-service/laokou-standalone/laokou-standalone-auth/laokou-standalone-auth-start/src/main/resources/application.yml[150-160]
- laokou-service/laokou-auth/laokou-auth-start/src/main/resources/application.yml[160-165]

## Suggested approach
1. Replace `/v1/captchas/{uuid}` with the two new endpoints in standalone ignore-patterns.
2. Add `/login` to standalone ignore-patterns if the standalone auth deployment serves the Thymeleaf login page.
3. Keep the existing send-mail/send-mobile POST allowlist as-is.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
4. Hardcoded login defaults 🐞 Bug ⛨ Security
Description
UI login form now hardcodes initial tenant_code, username, and password values
(laokouyun/admin/admin123), which risks accidental use of default credentials and exposes them in UI
by default.
Code

ui/src/pages/Login/index.tsx[R367-376]

+					initialValue={'laokouyun'}
					fieldProps={{
						size: 'large',
						prefix: <TeamOutlined className={'prefixIcon'} />,
						autoComplete: 'new-password',
					}}
+					allowClear={true}
					placeholder={t('login.tenantCode.placeholder')}
					rules={[
						{
Evidence
The login form inputs are pre-populated with specific credential-like values in code, which will be
shipped to all environments unless gated.

ui/src/pages/Login/index.tsx[364-416]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The login form ships with hardcoded default values for tenant, username, and password. This can lead to insecure deployments and accidental credential exposure.

## Issue Context
These values are rendered on the client for every user visiting the login page.

## Fix Focus Areas
- ui/src/pages/Login/index.tsx[364-416]

## Suggested approach
1. Remove `initialValue` for `tenant_code`, `username`, `password`.
2. If demo defaults are desired, guard them with an explicit dev-only build-time flag (e.g., `process.env.NODE_ENV === &#x27;development&#x27;`) and ensure production builds do not include them.
3. Add a test/lint rule to prevent committing plaintext password defaults.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

5. Login page CDN dependency 🐞 Bug ⛨ Security
Description
The new Thymeleaf login page loads Vue and ElementPlus directly from jsdelivr CDN without integrity
pinning, making login availability depend on external network access and increasing supply-chain
risk.
Code

laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html[R203-205]

+<script src="https://cdn.jsdelivr.net/npm/vue@3.4.30/dist/vue.global.prod.js"></script>
+<script src="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.full.min.js"></script>
+
Evidence
The login page includes external CSS/JS from a public CDN; if blocked or compromised, the login UI
may fail to load or could be tampered with.

laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html[9-11]
laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html[203-204]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The login page depends on third-party CDN resources without integrity protection, introducing availability and supply-chain risks.

## Issue Context
This is the primary authentication entrypoint; it should remain available even in restricted networks.

## Fix Focus Areas
- laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html[9-11]
- laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html[203-204]

## Suggested approach
1. Vendor Vue/ElementPlus assets into the project and serve them from `/static` or `/webjars`.
2. If keeping CDN, add Subresource Integrity (SRI) attributes and consider a local fallback if CDN fails.
3. Consider adding a CSP that restricts script sources appropriately.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

6. Malformed README image tag 🐞 Bug ⛯ Reliability
Description
README.md contains an invalid HTML attribute for an image height, which breaks README rendering and
documentation readability.
Code

README.md[66]

+<img src="doc/image/img_1.png" width=400 height=(免费用于毕设、二开、商用、二次开源)400 alt="COLA架构图"/>
Evidence
The image tag’s height attribute includes non-numeric text, making it invalid HTML in Markdown
rendering contexts.

README.md[66-66]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
README contains malformed HTML for an image tag, breaking rendering.

## Issue Context
The `height` attribute is not valid and includes unrelated text.

## Fix Focus Areas
- README.md[66-66]

## Suggested approach
Replace with a valid tag, e.g.:
- `&lt;img src=&quot;doc/image/img_1.png&quot; width=&quot;400&quot; height=&quot;400&quot; alt=&quot;COLA架构图&quot;/&gt;`

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了两个问题,并给出了一些总体反馈:

  • 在 React 登录页中,tenant_codeusernamepassword 的硬编码 initialValue 默认值(laokouyun / admin / admin123)在演示环境里很方便,但在生产环境存在安全风险;建议只在开发环境通过配置开关启用,或在非开发构建中移除这些默认值。
  • 在 README.md 中,修改后的 <img> 标签的 height 属性无效(height=(免费用于毕设、二开、商用、二次开源)400),会导致 HTML 解析出错;应当改回纯数字值,或把这段文字移到正文中。
给 AI Agent 的提示
Please address the comments from this code review:

## Overall Comments
- On the React login page, the hardcoded `initialValue` defaults for `tenant_code`, `username`, and `password` (`laokouyun` / `admin` / `admin123`) are convenient for demos but risky for production; consider gating them behind a development flag or removing them for non-dev builds.
- In README.md, the modified `<img>` tag has an invalid `height` attribute (`height=(免费用于毕设、二开、商用、二次开源)400`), which will break HTML parsing; this should be corrected to a numeric value or moved into the text.

## Individual Comments

### Comment 1
<location path="laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html" line_range="10-19" />
<code_context>
+  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"/>
</code_context>
<issue_to_address>
**🚨 suggestion (security):** Relying on unauthenticated CDN assets (Vue/Element Plus) on the login page can introduce availability and supply-chain risks.

Here you’re loading Element Plus from jsDelivr without Subresource Integrity or a local fallback. For an auth entrypoint, this increases exposure to CDN compromise/MITM and outages.

Prefer either:
- Self‑hosting a pinned version of this asset, or
- Adding `integrity` + `crossorigin` attributes and a local fallback.

This better controls the login surface and reduces dependency on third‑party infrastructure.

Suggested implementation:

```
  <!-- Element Plus(Vue3 UI)
       使用带 SRI 的 CDN + 本地回退,降低供应链与可用性风险 -->
  <link
    rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"
    integrity="<!-- TODO: replace with real SRI hash for element-plus@2.7.8/dist/index.css -->"
    crossorigin="anonymous"
    referrerpolicy="no-referrer"
  />
  <!-- 本地回退,当 CDN 不可用或被阻断时生效 -->
  <link
    rel="stylesheet"
    th:href="@{/static/element-plus/2.7.8/dist/index.css}"
    href="/static/element-plus/2.7.8/dist/index.css"
  />

```

1.`element-plus@2.7.8/dist/index.css` 下载到项目静态目录(示例为 `src/main/resources/static/element-plus/2.7.8/dist/index.css`)或根据你们现有静态资源路径调整 `th:href`/`href`2. 使用官方工具或本地计算生成该 CSS 文件的真实 SRI 值(例如:`openssl dgst -sha256 -binary index.css | openssl base64 -A`,然后拼成 `sha256-...`)并替换占位的 `integrity` 内容。
3. 如项目的静态资源路径不以 `/static` 开头,请同步更新 `th:href``href` 中的 URL 以符合现有约定。
</issue_to_address>

### Comment 2
<location path="README.md" line_range="66" />
<code_context>
 - 适用于中大型微服务IoT项目【业务复杂】

-<img src="doc/image/img_1.png" width=400 height=400 alt="COLA架构图"/>
+<img src="doc/image/img_1.png" width=400 height=(免费用于毕设、二开、商用、二次开源)400 alt="COLA架构图"/>
 <img src="doc/image/img.png" width=400 height=400 alt="COLA架构图"/>

</code_context>
<issue_to_address>
**issue (bug_risk):** Image `height` attribute appears corrupted and will likely break HTML rendering.

The `height` value currently contains the text `(免费用于毕设、二开、商用、二次开源)`, which makes the attribute invalid and prevents the height from being applied. Please change it back to a plain numeric value (e.g., `height=400`).
</issue_to_address>

Sourcery 对开源项目免费 —— 如果你觉得这些 Review 有帮助,欢迎分享 ✨
帮我变得更有用!请对每条评论点 👍 或 👎,我会根据你的反馈改进后续 Review。
Original comment in English

Hey - I've found 2 issues, and left some high level feedback:

  • On the React login page, the hardcoded initialValue defaults for tenant_code, username, and password (laokouyun / admin / admin123) are convenient for demos but risky for production; consider gating them behind a development flag or removing them for non-dev builds.
  • In README.md, the modified <img> tag has an invalid height attribute (height=(免费用于毕设、二开、商用、二次开源)400), which will break HTML parsing; this should be corrected to a numeric value or moved into the text.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- On the React login page, the hardcoded `initialValue` defaults for `tenant_code`, `username`, and `password` (`laokouyun` / `admin` / `admin123`) are convenient for demos but risky for production; consider gating them behind a development flag or removing them for non-dev builds.
- In README.md, the modified `<img>` tag has an invalid `height` attribute (`height=(免费用于毕设、二开、商用、二次开源)400`), which will break HTML parsing; this should be corrected to a numeric value or moved into the text.

## Individual Comments

### Comment 1
<location path="laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html" line_range="10-19" />
<code_context>
+  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"/>
</code_context>
<issue_to_address>
**🚨 suggestion (security):** Relying on unauthenticated CDN assets (Vue/Element Plus) on the login page can introduce availability and supply-chain risks.

Here you’re loading Element Plus from jsDelivr without Subresource Integrity or a local fallback. For an auth entrypoint, this increases exposure to CDN compromise/MITM and outages.

Prefer either:
- Self‑hosting a pinned version of this asset, or
- Adding `integrity` + `crossorigin` attributes and a local fallback.

This better controls the login surface and reduces dependency on third‑party infrastructure.

Suggested implementation:

```
  <!-- Element Plus(Vue3 UI)
       使用带 SRI 的 CDN + 本地回退,降低供应链与可用性风险 -->
  <link
    rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"
    integrity="<!-- TODO: replace with real SRI hash for element-plus@2.7.8/dist/index.css -->"
    crossorigin="anonymous"
    referrerpolicy="no-referrer"
  />
  <!-- 本地回退,当 CDN 不可用或被阻断时生效 -->
  <link
    rel="stylesheet"
    th:href="@{/static/element-plus/2.7.8/dist/index.css}"
    href="/static/element-plus/2.7.8/dist/index.css"
  />

```

1.`element-plus@2.7.8/dist/index.css` 下载到项目静态目录(示例为 `src/main/resources/static/element-plus/2.7.8/dist/index.css`)或根据你们现有静态资源路径调整 `th:href`/`href`2. 使用官方工具或本地计算生成该 CSS 文件的真实 SRI 值(例如:`openssl dgst -sha256 -binary index.css | openssl base64 -A`,然后拼成 `sha256-...`)并替换占位的 `integrity` 内容。
3. 如项目的静态资源路径不以 `/static` 开头,请同步更新 `th:href``href` 中的 URL 以符合现有约定。
</issue_to_address>

### Comment 2
<location path="README.md" line_range="66" />
<code_context>
 - 适用于中大型微服务IoT项目【业务复杂】

-<img src="doc/image/img_1.png" width=400 height=400 alt="COLA架构图"/>
+<img src="doc/image/img_1.png" width=400 height=(免费用于毕设、二开、商用、二次开源)400 alt="COLA架构图"/>
 <img src="doc/image/img.png" width=400 height=400 alt="COLA架构图"/>

</code_context>
<issue_to_address>
**issue (bug_risk):** Image `height` attribute appears corrupted and will likely break HTML rendering.

The `height` value currently contains the text `(免费用于毕设、二开、商用、二次开源)`, which makes the attribute invalid and prevents the height from being applied. Please change it back to a plain numeric value (e.g., `height=400`).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +10 to +19
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"/>

<style>
:root{
--brand: #1677ff;
--bg1: #0b1220;
--bg2: #0e1a2b;
--card: rgba(255,255,255,.92);
--cardBorder: rgba(255,255,255,.35);
--text: rgba(0,0,0,.88);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 suggestion (security): 在登录页依赖未经验证的 CDN 资源(Vue / Element Plus),会带来可用性和供应链方面的风险。

当前你是从 jsDelivr 加载 Element Plus,但没有使用子资源完整性(Subresource Integrity,SRI),也没有本地回退方案。对于认证入口页面来说,这会增加在 CDN 被攻破、中间人攻击(MITM)以及 CDN 宕机时的风险暴露面。

建议改为:

  • 自行托管一份固定版本的静态资源,或
  • 在使用 CDN 时增加 integrity + crossorigin 属性,并提供本地回退资源。

这样可以更好地控制登录入口的安全面,并降低对第三方基础设施的依赖。

建议的实现方式:

  <!-- Element Plus(Vue3 UI)
       使用带 SRI 的 CDN + 本地回退,降低供应链与可用性风险 -->
  <link
    rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"
    integrity="<!-- TODO: replace with real SRI hash for element-plus@2.7.8/dist/index.css -->"
    crossorigin="anonymous"
    referrerpolicy="no-referrer"
  />
  <!-- 本地回退,当 CDN 不可用或被阻断时生效 -->
  <link
    rel="stylesheet"
    th:href="@{/static/element-plus/2.7.8/dist/index.css}"
    href="/static/element-plus/2.7.8/dist/index.css"
  />

  1. element-plus@2.7.8/dist/index.css 下载到项目静态目录(示例为 src/main/resources/static/element-plus/2.7.8/dist/index.css)或根据你们现有静态资源路径调整 th:href/href
  2. 使用官方工具或本地计算生成该 CSS 文件的真实 SRI 值(例如:openssl dgst -sha256 -binary index.css | openssl base64 -A,然后拼成 sha256-...)并替换占位的 integrity 内容。
  3. 如项目的静态资源路径不以 /static 开头,请同步更新 th:hrefhref 中的 URL 以符合现有约定。
Original comment in English

🚨 suggestion (security): Relying on unauthenticated CDN assets (Vue/Element Plus) on the login page can introduce availability and supply-chain risks.

Here you’re loading Element Plus from jsDelivr without Subresource Integrity or a local fallback. For an auth entrypoint, this increases exposure to CDN compromise/MITM and outages.

Prefer either:

  • Self‑hosting a pinned version of this asset, or
  • Adding integrity + crossorigin attributes and a local fallback.

This better controls the login surface and reduces dependency on third‑party infrastructure.

Suggested implementation:

  <!-- Element Plus(Vue3 UI)
       使用带 SRI 的 CDN + 本地回退,降低供应链与可用性风险 -->
  <link
    rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"
    integrity="<!-- TODO: replace with real SRI hash for element-plus@2.7.8/dist/index.css -->"
    crossorigin="anonymous"
    referrerpolicy="no-referrer"
  />
  <!-- 本地回退,当 CDN 不可用或被阻断时生效 -->
  <link
    rel="stylesheet"
    th:href="@{/static/element-plus/2.7.8/dist/index.css}"
    href="/static/element-plus/2.7.8/dist/index.css"
  />

  1. element-plus@2.7.8/dist/index.css 下载到项目静态目录(示例为 src/main/resources/static/element-plus/2.7.8/dist/index.css)或根据你们现有静态资源路径调整 th:href/href
  2. 使用官方工具或本地计算生成该 CSS 文件的真实 SRI 值(例如:openssl dgst -sha256 -binary index.css | openssl base64 -A,然后拼成 sha256-...)并替换占位的 integrity 内容。
  3. 如项目的静态资源路径不以 /static 开头,请同步更新 th:hrefhref 中的 URL 以符合现有约定。

- 适用于中大型微服务IoT项目【业务复杂】

<img src="doc/image/img_1.png" width=400 height=400 alt="COLA架构图"/>
<img src="doc/image/img_1.png" width=400 height=(免费用于毕设、二开、商用、二次开源)400 alt="COLA架构图"/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): 图片的 height 属性似乎已被破坏,很可能会导致 HTML 渲染异常。

当前 height 的值包含文本 (免费用于毕设、二开、商用、二次开源),这会使该属性变成无效值,导致高度设置无法生效。请将其改回纯数字值(例如 height=400)。

Original comment in English

issue (bug_risk): Image height attribute appears corrupted and will likely break HTML rendering.

The height value currently contains the text (免费用于毕设、二开、商用、二次开源), which makes the attribute invalid and prevents the height from being applied. Please change it back to a plain numeric value (e.g., height=400).

Comment on lines +384 to 388
return List.of(GrantType.USERNAME_PASSWORD, GrantType.MOBILE, GrantType.MAIL, GrantType.AUTHORIZATION_CODE)
.contains(grantType);
}

private boolean isUsePassword() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Auth-code captcha null 🐞 Bug ✓ Correctness

AuthA now requires captcha for AUTHORIZATION_CODE but createAuthorizationCodeAuth() never
initializes captchaV, so DomainService.auth() will hit a NullPointerException in checkCaptcha() when
captchaV is dereferenced.
Agent Prompt
## Issue description
AUTHORIZATION_CODE auth now goes through captcha validation, but `AuthA.createAuthorizationCodeAuth()` never sets `captchaV`. This makes `AuthA.checkCaptcha()` dereference `captchaV` and crash with a NullPointerException.

## Issue Context
- `DomainService.auth()` always invokes `authA.checkCaptcha()`.
- `isUseCaptcha()` includes `GrantType.AUTHORIZATION_CODE`.
- `checkCaptcha()` reads `this.captchaV.captcha()` and `getCaptchaCacheKeyByAuth()` reads `this.captchaV.uuid()`.

## Fix Focus Areas
- laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[220-224]
- laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[323-333]
- laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[383-400]
- laokou-service/laokou-auth/laokou-auth-app/src/main/java/org/laokou/auth/service/validator/AuthorizationCodeAuthParamValidator.java[37-47]

## Suggested approach
1. Add a method like `getCaptchaVByAuthorizationCodeAuth()` (similar to username-password) that reads `uuid` and `captcha` parameters.
2. In `createAuthorizationCodeAuth()`, set `this.captchaV = getCaptchaVByAuthorizationCodeAuth()`.
3. Update `AuthorizationCodeAuthParamValidator` to validate the captcha-related parameters if captcha is required for this grant type.
4. Alternatively (if captcha is not intended for AUTHORIZATION_CODE), remove it from `isUseCaptcha()` and from `getCaptchaCacheKeyByAuth()`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +196 to +202
- /api/v1/username-password/captchas/{uuid}=laokou-gateway
- /api/v1/authorization-code/captchas/{uuid}=laokou-gateway
- /api/v1/secrets=laokou-gateway
- /doc.html=laokou-gateway
- /webjars/**=laokou-gateway
- /ws=laokou-gateway
- /api/login=laokou-gateway

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Gateway login path mismatch 🐞 Bug ⛯ Reliability

Gateway unauthenticated allowlist includes GET /api/login but the auth server exposes the login page
at /login, so accessing /login through the gateway will not match the allowlist and will be blocked
by AuthFilter as Unauthorized.
Agent Prompt
## Issue description
Gateway allowlist permits `GET /api/login`, but the auth service login page is `GET /login` and Spring Security processes `POST /login`. Gateway `AuthFilter` blocks any request not in the allowlist when no Authorization header is present, making the login page unreachable through the gateway.

## Issue Context
- Gateway relies on `request-matcher.ignore-patterns` to bypass auth.
- Auth service uses `/login` for login page and login processing.

## Fix Focus Areas
- laokou-cloud/laokou-gateway/src/main/resources/application.yml[190-206]
- laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/LoginController.java[29-32]
- laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2ResourceServerConfig.java[67-71]

## Suggested approach
1. Add `GET /login=laokou-gateway` and `POST /login=laokou-gateway` to the gateway ignore-patterns.
2. Remove or repurpose `/api/login` unless a real route exists.
3. If the intended public endpoint is `/api/login`, change the auth controller + Spring Security loginPage/loginProcessingUrl to `/api/login` and ensure templates resolve correctly.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +160 to +165
- /v1/username-password/captchas/{uuid}=laokou-auth
- /v1/authorization-code/captchas/{uuid}=laokou-auth
- /v1/secrets=laokou-auth
- /doc.html=laokou-auth
- /webjars/**=laokou-auth
- /login=laokou-auth

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Standalone captcha whitelist stale 🐞 Bug ⛯ Reliability

Standalone auth resource-server ignore-patterns still whitelist only /v1/captchas/{uuid}, so the new
captcha endpoints won’t be publicly accessible in standalone mode and login flows that need captcha
will be blocked.
Agent Prompt
## Issue description
Standalone auth configuration still whitelists the removed captcha endpoint `/v1/captchas/{uuid}` and does not whitelist the new captcha endpoints. This blocks captcha retrieval pre-auth in standalone deployments.

## Issue Context
Auth service has migrated to:
- `/v1/username-password/captchas/{uuid}`
- `/v1/authorization-code/captchas/{uuid}`

## Fix Focus Areas
- laokou-service/laokou-standalone/laokou-standalone-auth/laokou-standalone-auth-start/src/main/resources/application.yml[150-160]
- laokou-service/laokou-auth/laokou-auth-start/src/main/resources/application.yml[160-165]

## Suggested approach
1. Replace `/v1/captchas/{uuid}` with the two new endpoints in standalone ignore-patterns.
2. Add `/login` to standalone ignore-patterns if the standalone auth deployment serves the Thymeleaf login page.
3. Keep the existing send-mail/send-mobile POST allowlist as-is.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +367 to 376
initialValue={'laokouyun'}
fieldProps={{
size: 'large',
prefix: <TeamOutlined className={'prefixIcon'} />,
autoComplete: 'new-password',
}}
allowClear={true}
placeholder={t('login.tenantCode.placeholder')}
rules={[
{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

4. Hardcoded login defaults 🐞 Bug ⛨ Security

UI login form now hardcodes initial tenant_code, username, and password values
(laokouyun/admin/admin123), which risks accidental use of default credentials and exposes them in UI
by default.
Agent Prompt
## Issue description
The login form ships with hardcoded default values for tenant, username, and password. This can lead to insecure deployments and accidental credential exposure.

## Issue Context
These values are rendered on the client for every user visiting the login page.

## Fix Focus Areas
- ui/src/pages/Login/index.tsx[364-416]

## Suggested approach
1. Remove `initialValue` for `tenant_code`, `username`, `password`.
2. If demo defaults are desired, guard them with an explicit dev-only build-time flag (e.g., `process.env.NODE_ENV === 'development'`) and ensure production builds do not include them.
3. Add a test/lint rule to prevent committing plaintext password defaults.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
3 Security Hotspots
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant