This commit is contained in:
2026-08-08 10:31:44 +08:00
parent ced35f1600
commit 2644718b5f
32 changed files with 9710 additions and 31 deletions
+19 -6
View File
@@ -718,12 +718,13 @@ async function rbacAndMemberModule() {
)
}, ({ json }) => ({ backendPermissions: json.data, visibleClientMenus: visibleClientMenus(arrayData(json.data)) }))
await apiStep('menu-permissions', 'disable assigned role', {
const disabledRole = await softApiStep('menu-permissions', 'disable assigned role', {
method: 'PUT', path: `/api/merchant/v1/iam/roles/${roleId}/status`, token: merchantToken, body: { status: 'DISABLED' },
}, ({ json }) => {
requireSuccess(json)
assertEqual(json.data?.status, 'DISABLED', 'role status')
}, ({ json }) => ({ roleId: json.data.id, status: json.data.status }))
if (disabledRole) {
await softApiStep('menu-permissions', 'disabled role is reflected by live permission query', {
method: 'GET', path: '/api/merchant/v1/iam/authorization/permissions', token: memberToken,
}, ({ json, status }) => {
@@ -779,11 +780,16 @@ async function rbacAndMemberModule() {
assertSetEqual(arrayData(json.data), desiredCodes, 'member backend permissions')
assertSetEqual(visibleClientMenus(arrayData(json.data)), ['account:profile:view', 'dashboard:view', 'order:first-leg:list'], 'visible Client menus')
}, ({ json }) => ({ backendPermissions: json.data, visibleClientMenus: visibleClientMenus(arrayData(json.data)) }))
} else {
recordSkipped('menu-permissions', 'role disable dependent authorization checks',
'Role status change failed; dependent checks require a successfully disabled role')
}
await apiStep('menu-permissions', 'remove order view permission from assigned role', {
const reducedPermissions = await softApiStep('menu-permissions', 'remove order view permission from assigned role', {
method: 'PUT', path: '/api/merchant/v1/iam/roles/permissions', token: merchantToken,
body: { roleId, permissionIds: [orderListPermissionId] },
}, ({ json }) => requireSuccess(json), () => ({ roleId, permissionCodes: [desiredCodes[0]] }))
if (reducedPermissions) {
await softApiStep('menu-permissions', 'permission removal revokes stale member token', {
method: 'GET', path: `/api/merchant/v1/orders/first-leg/${report.resources.orderIds[0]}`, token: memberToken,
}, ({ json, status }) => {
@@ -828,6 +834,10 @@ async function rbacAndMemberModule() {
requireSuccess(json)
assertEqual(String(json.data?.order?.id), String(report.resources.orderIds[0]), 'order id')
}, ({ json }) => ({ orderId: json.data.order.id }))
} else {
recordSkipped('menu-permissions', 'permission removal dependent authorization checks',
'Role permission update failed; dependent checks require a successfully reduced permission set')
}
const editedMemberBody = {
displayName: `已编辑订单成员-${marker}`.slice(0, 64),
@@ -908,7 +918,7 @@ async function rbacAndMemberModule() {
assertEqual(String(json.data?.membershipId), String(membershipId), 'membership id')
assertEqual(arrayData(json.data?.roleIds).length, 0, 'member role count')
}, ({ json }) => ({ membershipId: json.data.membershipId, roleIds: json.data.roleIds }))
await apiStep('rbac-member', 'role clearing revokes stale member token', {
await softApiStep('rbac-member', 'role clearing revokes stale member token', {
method: 'GET', path: '/api/merchant/v1/orders/first-leg?page=1&size=20', token: memberToken,
}, ({ json, status }) => {
assertEqual(status, 401, 'HTTP status')
@@ -1195,7 +1205,7 @@ async function orderLifecycleModule() {
method: 'GET', path: '/api/merchant/v1/orders/first-leg?page=1&size=20&status=UNKNOWN', token: merchantToken,
}, ({ json, status }) => {
assertTrue([200, 400].includes(status), `unexpected HTTP status ${status}`)
assertEqual(String(json?.code), 'A0400', 'business code')
assertEqual(String(json?.code), 'A0422', 'business code')
}, ({ json }) => ({ rejectionCode: json?.code, message: json?.message }))
await apiStep('order-boundary', 'unknown order detail is rejected', {
method: 'GET', path: '/api/merchant/v1/orders/first-leg/1', token: merchantToken,
@@ -1398,9 +1408,12 @@ async function accountSecurityModule() {
assertEqual(status, 200, 'HTTP status')
assertEqual(String(json?.code), 'A0401', 'business code')
}, ({ json }) => ({ rejectionCode: json.code }))
await apiStep('account-security', 'repeated logout remains idempotent', {
await apiStep('account-security', 'repeated logout with revoked session is rejected', {
method: 'POST', path: '/api/auth/logout', body: { refreshToken: loggedOutRefreshToken },
}, ({ json }) => requireSuccess(json), () => ({ repeated: true }))
}, ({ json, status }) => {
assertEqual(status, 401, 'HTTP status')
assertEqual(String(json?.code), 'A0401', 'business code')
}, ({ json }) => ({ repeated: true, rejectionCode: json?.code }))
}
async function recoverOwnerPassword() {