ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

ToolJet 用户个人资料设置完整指南:更新姓名、头像与修改密码

ToolJet 用户个人资料设置完整指南:更新姓名、头像与修改密码 ToolJet 用户个人资料设置完整指南更新姓名、头像与修改密码【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet本篇技术指南基于 ToolJet 官方文档中关于Profile Settings个人资料设置的说明并结合仓库内前端页面、前端服务层与后端 NestJS 模块的源码实现完整讲解如何在 ToolJet 中修改用户名、上传头像以及安全地修改密码。读完本文你将掌握个人资料设置页的入口与路由、前端表单校验逻辑、前后端接口调用链路、密码强度规则与底层安全机制并能依据 Cypress 测试用例验证相关行为。个人资料设置功能概览与入口在 ToolJet 中每个用户都可以通过Profile Settings页面管理自己的基础账户信息包括更新自己的姓名first name / last name上传个人头像avatar修改登录密码原文档给出的操作入口非常简单点击仪表盘左下角的设置图标⚙️进入 Profile Settings。文档中给出的示例 URL 形如https://app.corp.com/nexus/settings其中nexus为工作区标识。在仓库前端路由中该页面对应的真实路由为/:workspaceId/profile-settings见 frontend/src/App/App.jsx路由别名定义在 frontend/src/_helpers/routes.jsprofile_settings: /profile-settings。页面组件实现在 frontend/src/SettingsPage/SettingsPage.jsx通过 frontend/src/SettingsPage/index.js 导出属于frontend/src/SettingsPage/目录下的独立页面模块。进入页面后会看到两张并排的卡片源码中为两个card profile-page-card结构Profile编辑姓名、上传头像底部为Update按钮Change password输入当前密码、新密码并确认底部为Change password按钮。更新个人资料姓名与头像姓名编辑与前后端处理Profile 卡片中姓名输入框name-input-field预填了当前登录用户的完整姓名。前端使用joinNames将first_name与last_name拼接显示点击Update时又通过handleNameSplit按空格拆分为名与姓最后一个空格之后的部分视为 last name再调用服务层接口见 frontend/src/SettingsPage/SettingsPage.jsx。前端校验规则姓名不能为空fullName.match(/^ *$/)命中时直接提示Name cant be empty!。对应的前端服务层实现位于 frontend/src/_services/user.service.jsfunction updateCurrentUser(firstName, lastName) { const body { first_name: firstName, last_name: lastName }; const requestOptions { method: PATCH, headers: authHeader(), credentials: include, body: JSON.stringify(body) }; return fetch(${config.apiUrl}/profile, requestOptions).then(handleResponse); }即向PATCH /api/profile提交{ first_name, last_name }。后端由ProfileController处理见 server/src/modules/profile/controller.ts在update方法中调用profileService.updateUserName完成数据库更新随后返回更新后的first_name与last_name。底层服务实现见 server/src/modules/profile/service.ts通过dbTransactionWrap在事务内完成更新并写入审计日志AUDIT_LOGS_REQUEST_CONTEXT_KEY记录previous_user_details与updated_user_details的字段级前后对比。更新成功后前端会同步刷新本地会话状态authenticationService.updateCurrentSession({ ...authenticationService.currentSessionValue, current_user: { ... /* first_name, last_name, avatar_id */ }, isUserUpdated: true, });这样侧边栏、页面头部等使用会话数据的地方能立即反映新姓名。头像上传与格式限制头像输入框为文件选择控件源码中做了两层限制见 frontend/src/SettingsPage/SettingsPage.jsx文件类型仅允许image/jpeg、image/png、image/gif、image/webp否则提示Only JPEG, PNG, GIF, and WebP images are allowed文件大小不得超过 2MBMath.round(file.size / 1024) 2048时拒绝否则提示File size cannot exceed more than 2MB。前端通过FormData携带文件调用userService.updateAvatar见 frontend/src/_services/user.service.jsfunction updateAvatar(formData) { const requestOptions { method: PATCH, headers: authHeader(true), // 注意上传文件时不手动设置 Content-Type交由浏览器自动生成 multipart boundary body: formData, credentials: include, }; return fetch(${config.apiUrl}/profile/avatar, requestOptions).then(handleResponse); }后端对应PATCH /profile/avatar接口见 server/src/modules/profile/controller.tsPatch(avatar) UseInterceptors(FileInterceptor(file)) async addAvatar( User() user: UserEntity, UploadedFile( new ParseFilePipe({ validators: [ new MaxFileSizeValidator({ maxSize: MAX_AVATAR_FILE_SIZE }), new ImageMagicBytesValidator(), ], }) ) file: any ) { return this.profileService.addAvatar(user.id, file?.buffer, file?.originalname); }其中MAX_AVATAR_FILE_SIZE 1024 * 1024 * 22MB见 server/src/modules/profile/constants/index.ts与前端限制保持一致。除大小校验外后端还通过ImageMagicBytesValidator实现于 server/src/modules/profile/image-magic-bytes.validator.ts用魔数magic bytes校验文件真实类型防止伪造扩展名的非图片文件上传形成前端 后端双重防护。头像的数据库落盘由ProfileService.addAvatar完成见 server/src/modules/profile/service.ts同样在事务中执行并写入包含头像变更前后avatar_id的审计日志。成功后前端把返回的avatar.id写入本地会话中的avatar_id。邮箱字段为只读Profile 卡片中邮箱Email address输入框带有readOnly与disabled属性见 frontend/src/SettingsPage/SettingsPage.jsx值来自当前会话的current_user.email。也就是说邮箱是账户标识不能在此页面修改如需更换邮箱应走管理员或系统层面的用户管理流程。修改密码前端校验到后端安全链前端表单与交互细节Change password 卡片包含三个密码输入框Current password当前密码、New password新密码、Confirm new password确认新密码。源码中的前端校验与交互行为如下见 frontend/src/SettingsPage/SettingsPage.jsx非空校验三个字段任一为空都会提示对应字段cant be empty!新旧密码不同新密码与当前密码相同时提示New password cant be the same as the current one!两次输入一致新密码与确认密码不一致时提示New password and confirm new password should be same最小长度新密码与确认密码少于 5 个字符时Change password按钮处于禁用状态disabled{newPassword.trim().length 5 || confirmPassword.trim().length 5 || !validPassword}键盘交互在新密码框按 Enter 会聚焦到确认密码框在确认密码框按 Enter 直接触发changePassword()。接口调用链前端调用userService.changePassword见 frontend/src/_services/user.service.jsfunction changePassword(currentPassword, newPassword) { const body { currentPassword, newPassword }; const requestOptions { method: PATCH, headers: authHeader(), credentials: include, body: JSON.stringify(body) }; return fetch(${config.apiUrl}/profile/password, requestOptions).then(handleResponse); }后端PATCH /profile/password接口定义在 server/src/modules/profile/controller.ts同时挂载了PasswordRevalidateGuard守卫。当前密码的二次验证PasswordRevalidateGuard修改密码最关键的环节是验证“当前密码是否正确”。后端通过 server/src/modules/profile/guards/password-revalidate.guard.ts 完成从请求体中取出currentPassword与数据库中该用户按request.user.email查询的密码哈希做bcrypt.compare比对。只有比对通过才会继续执行密码更新逻辑。这是保证安全性的关键一步——仅凭已登录的会话并不足以修改密码还必须证明你确实知道当前密码。服务端密码强度校验validatePasswordServer真正的密码规则校验在服务端执行。ProfileService.updateUserPassword首先调用validatePasswordServer(password)见 server/src/helpers/utils.helper.ts该函数根据部署版本有不同的规则企业版EE且开启复杂度规则TOOLJET_EDITIONee且ENABLE_PASSWORD_COMPLEXITY_RULEStrue密码必须匹配正则/^(?.{12,24}$)[A-Za-z0-9!#$%^*()_\-{}[\]:;,.?/\\|]$/即12–24 个字符可包含字母、数字和特殊字符。不满足时抛出Password must be 12–24 characters and may include letters, numbers and special characters。社区版CE或未开启复杂度规则要求非空、至少 5 个字符、最长 100 个字符。有意思的是前端对后端返回的错误做了专门映射见 frontend/src/SettingsPage/SettingsPage.jsx如果后端消息恰为上述 12–24 字符的复杂度提示则原样展示给用户否则统一显示Please verify that you have entered the correct password避免向用户泄露具体是“当前密码错误”还是其他细节同时兼容不同部署版本的密码规则差异。密码更新后的副作用ProfileService.updateUserPassword见 server/src/modules/profile/service.ts在事务内完成通过validatePasswordServer校验新密码合法性更新password字段重置passwordRetryCount为 0登录失败重试计数归零根据环境变量PASSWORD_EXPIRY_DAYS默认0表示不启用计算passwordExpiry过期时间写入审计日志。这也解释了前端在密码修改成功后清空三个输入框的行为——密码已经生效输入框不应再保留敏感数据。接口权限与安全机制小结ProfileController整体声明为Controller(profile)并挂载了JwtAuthGuard与FeatureAbilityGuard见 server/src/modules/profile/controller.ts意味着所有个人资料接口都要求有效的 JWT 登录态通过InitFeatureget/update/update_avatar/update_password见 server/src/modules/profile/constants/index.ts接入基于能力ability的细粒度权限控制。结合前文个人资料模块的安全设计可以总结为四层层面机制源码位置身份认证JwtAuthGuard 校验登录态controller.ts权限控制FeatureAbilityGuard InitFeature 细粒度能力ability/guard.ts密码验证PasswordRevalidateGuard bcrypt.comparepassword-revalidate.guard.ts审计追踪事务内写入变更前后字段的审计日志service.ts测试覆盖与行为验证仓库的 Cypress 测试对个人资料设置页进行了完整覆盖见 cypress-tests/cypress/e2e/happyPath/platform/commonTestcases/workspace/workspaceUiTestcases/profile.cy.js可以直接作为功能验收清单访问/my-workspace/profile-settings并验证页面元素渲染姓名重置修改姓名后出现成功提示且头像图片样式background-image随之更新头像上传通过selectFile选择cypress/fixtures/Image/tooljet.png上传验证头像展示密码修改覆盖“新旧密码相同”“两次输入不一致”“任一字段为空”等负向场景以及正常修改密码后成功提示并使用新密码重新登录验证修改真正生效测试文件顶部注释也特别提醒密码变更后运行一次会导致后续请求 401需要重置数据库种子数据。常见问题与注意事项忘记当前密码怎么办修改密码必须提供正确的当前密码后端 bcrypt 校验无法绕过。忘记密码应使用登录页的找回密码流程而非个人资料页。密码复杂度规则取决于部署版本CE 默认 5–100 字符即可EE 开启ENABLE_PASSWORD_COMPLEXITY_RULEStrue后强制 12–24 字符复杂度。前端按钮仅做 5 字符的最小禁用判断最终强校验以服务端validatePasswordServer为准。头像格式受限仅支持 JPEG、PNG、GIF、WebP且不得超过 2MB后端会再次用魔数校验真实文件类型。邮箱不可在个人资料页修改邮箱字段为只读属于账户标识。通过本文的文档说明 源码佐证你可以完整掌握 ToolJet 个人资料设置页的实现原理、接口链路与安全机制无论是在实际使用中操作还是在此基础上二次开发都能有的放矢。【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表