mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-16 04:18:17 +08:00
fix(approval): three minor issues surfaced by end-to-end testing
This commit is contained in:
parent
f15b2dced3
commit
2f5e06f286
@ -141,7 +141,12 @@ public class ApprovalGrantController {
|
|||||||
public R<Map<String, Object>> activeSummary(
|
public R<Map<String, Object>> activeSummary(
|
||||||
@RequestHeader(value = "X-Workspace-Id", required = false) Long workspaceId) {
|
@RequestHeader(value = "X-Workspace-Id", required = false) Long workspaceId) {
|
||||||
Long ws = workspaceId != null ? workspaceId : DEFAULT_WORKSPACE_ID;
|
Long ws = workspaceId != null ? workspaceId : DEFAULT_WORKSPACE_ID;
|
||||||
long count = grantService.countActiveInWorkspace(ws);
|
// Cast to int: this is a per-workspace grant count, never bigger than a
|
||||||
|
// few hundred. Returning Long here would be serialized as a JSON string
|
||||||
|
// by the global Long→String serializer (CLAUDE.md precision convention
|
||||||
|
// for snowflake ids), but count is not a snowflake — the frontend wants
|
||||||
|
// a real number for the chip badge and `count > 0` checks.
|
||||||
|
int count = (int) Math.min(grantService.countActiveInWorkspace(ws), Integer.MAX_VALUE);
|
||||||
// hasWorkspaceWide: workspace + tool_name IS NULL — the dangerous one.
|
// hasWorkspaceWide: workspace + tool_name IS NULL — the dangerous one.
|
||||||
Long workspaceWide = grantMapper.selectCount(
|
Long workspaceWide = grantMapper.selectCount(
|
||||||
Wrappers.<ApprovalGrant>lambdaQuery()
|
Wrappers.<ApprovalGrant>lambdaQuery()
|
||||||
|
|||||||
@ -131,10 +131,16 @@ public class AuthService {
|
|||||||
public void verifyCurrentUserPassword(Long userId, String rawPassword) {
|
public void verifyCurrentUserPassword(Long userId, String rawPassword) {
|
||||||
UserEntity user = userMapper.selectById(userId);
|
UserEntity user = userMapper.selectById(userId);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new MateClawException("err.auth.user_not_found", "用户不存在");
|
// 404: target user no longer exists; surfacing as 401 would mask the cause.
|
||||||
|
throw new MateClawException("err.auth.user_not_found", 404, "用户不存在");
|
||||||
}
|
}
|
||||||
if (rawPassword == null || !passwordEncoder.matches(rawPassword, user.getPassword())) {
|
if (rawPassword == null || !passwordEncoder.matches(rawPassword, user.getPassword())) {
|
||||||
throw new MateClawException("err.auth.wrong_password", "原密码错误");
|
// 403, not 401: 401 would trigger the global http interceptor's
|
||||||
|
// handleAuthFailure() and log the user out, but this is a step-up
|
||||||
|
// re-confirmation (token is still valid). Falling through to the
|
||||||
|
// default 500 looks like a server fault on the client; 403 cleanly
|
||||||
|
// communicates "valid session, wrong second-factor".
|
||||||
|
throw new MateClawException("err.auth.wrong_password", 403, "原密码错误");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,9 @@ export default {
|
|||||||
create: 'Create',
|
create: 'Create',
|
||||||
update: 'Update',
|
update: 'Update',
|
||||||
loading: 'Loading...',
|
loading: 'Loading...',
|
||||||
|
processing: 'Processing...',
|
||||||
|
success: 'Done',
|
||||||
|
revoked: 'Revoked',
|
||||||
enabled: 'Enabled',
|
enabled: 'Enabled',
|
||||||
disabled: 'Disabled',
|
disabled: 'Disabled',
|
||||||
default: 'Default',
|
default: 'Default',
|
||||||
|
|||||||
@ -13,6 +13,9 @@ export default {
|
|||||||
create: '创建',
|
create: '创建',
|
||||||
update: '更新',
|
update: '更新',
|
||||||
loading: '加载中...',
|
loading: '加载中...',
|
||||||
|
processing: '处理中...',
|
||||||
|
success: '操作成功',
|
||||||
|
revoked: '已撤销',
|
||||||
enabled: '启用',
|
enabled: '启用',
|
||||||
disabled: '停用',
|
disabled: '停用',
|
||||||
default: '默认',
|
default: '默认',
|
||||||
|
|||||||
@ -53,7 +53,7 @@
|
|||||||
@click="confirmRevoke(g)">
|
@click="confirmRevoke(g)">
|
||||||
{{ t('approval.grant.revokeBtn') }}
|
{{ t('approval.grant.revokeBtn') }}
|
||||||
</button>
|
</button>
|
||||||
<span v-else class="muted">{{ t('common.revoked') || 'revoked' }}</span>
|
<span v-else class="muted">{{ t('common.revoked') }}</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -244,7 +244,7 @@ async function submitCreate() {
|
|||||||
payload.password = form.password
|
payload.password = form.password
|
||||||
}
|
}
|
||||||
await approvalApi.createGrant(payload)
|
await approvalApi.createGrant(payload)
|
||||||
ElMessage.success(t('common.success') || 'Created')
|
ElMessage.success(t('common.success'))
|
||||||
dialogOpen.value = false
|
dialogOpen.value = false
|
||||||
await loadGrants()
|
await loadGrants()
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
@ -266,7 +266,7 @@ async function confirmRevoke(g: ApprovalGrant) {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await approvalApi.revokeGrant(g.id)
|
await approvalApi.revokeGrant(g.id)
|
||||||
ElMessage.success(t('common.success') || 'Revoked')
|
ElMessage.success(t('common.success'))
|
||||||
await loadGrants()
|
await loadGrants()
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
ElMessage.error(e?.message || 'Failed to revoke')
|
ElMessage.error(e?.message || 'Failed to revoke')
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user