mirror of
https://github.com/hansjone/dsh-ops-cron.git
synced 2026-10-08 23:20:45 +08:00
Hide unclaimed cron jobs from non-admin viewers.
Unassigned jobs are visible only to super_admin / fallback_admin (canViewAll). Regular users still reclaim jobs proven by session owner or their user-workspaces cwd. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
9a4662ca7c
commit
d1127dba88
2 changed files with 11 additions and 26 deletions
|
|
@ -23,14 +23,8 @@ export function jobVisibleToIdentity(job, identity) {
|
|||
if (!identity?.empNo) return false
|
||||
if (canViewAllJobs(identity)) return true
|
||||
const owner = normalizeOwnerEmpNo(job?.ownerEmpNo)
|
||||
// Legacy / tool-created rows often lack ownerEmpNo. Keep them visible so the
|
||||
// sidebar is not empty, then claimUnassignedForViewer can adopt them — unless
|
||||
// the cwd clearly belongs to another user.
|
||||
if (owner === UNASSIGNED_OWNER) {
|
||||
const pathOwner = empNoFromUserWorkspacePath(job?.cwd)
|
||||
if (pathOwner && pathOwner !== String(identity.empNo)) return false
|
||||
return true
|
||||
}
|
||||
// Unclaimed jobs are admin-only (super_admin / fallback_admin via canViewAll).
|
||||
if (owner === UNASSIGNED_OWNER) return false
|
||||
return owner === String(identity.empNo)
|
||||
}
|
||||
|
||||
|
|
@ -140,23 +134,14 @@ export function claimUnassignedForViewer(state, identity, deps = {}) {
|
|||
? job.origin.sessionId.trim()
|
||||
: ''
|
||||
let mine = false
|
||||
// Prefer session ownership / user-workspaces cwd. Adopt web/legacy orphans when
|
||||
// no other owner is known so chat-created jobs reappear in the sidebar.
|
||||
// Only claim when evidence ties the job to this viewer. Remaining unassigned
|
||||
// jobs stay admin-only until a super/fallback admin reassigns them.
|
||||
if (sessionId && typeof deps.getSessionOwner === 'function') {
|
||||
const sessionOwner = deps.getSessionOwner(sessionId)
|
||||
if (sessionOwner && sessionOwner !== identity.empNo) return job
|
||||
mine = !sessionOwner || sessionOwner === identity.empNo
|
||||
mine = deps.getSessionOwner(sessionId) === identity.empNo
|
||||
}
|
||||
if (!mine && job.cwd) {
|
||||
const norm = String(job.cwd).replace(/\\/g, '/')
|
||||
const match = norm.match(/\/user-workspaces\/([^/]+)(?:\/|$)/)
|
||||
if (match) {
|
||||
if (decodeURIComponent(match[1]) === identity.empNo) mine = true
|
||||
else return job
|
||||
}
|
||||
}
|
||||
if (!mine && job.origin?.kind !== 'im') {
|
||||
mine = true
|
||||
const pathOwner = empNoFromUserWorkspacePath(job.cwd)
|
||||
if (pathOwner === identity.empNo) mine = true
|
||||
}
|
||||
if (!mine) return job
|
||||
changed = true
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ test('jobVisibleToIdentity respects canViewAll and owner', () => {
|
|||
const admin = { empNo: 'a1', permissions: { canViewAllSessions: true } }
|
||||
assert.equal(jobVisibleToIdentity({ ownerEmpNo: 'u1' }, user), true)
|
||||
assert.equal(jobVisibleToIdentity({ ownerEmpNo: 'u2' }, user), false)
|
||||
assert.equal(jobVisibleToIdentity({ ownerEmpNo: UNASSIGNED_OWNER }, user), true)
|
||||
assert.equal(jobVisibleToIdentity({ ownerEmpNo: UNASSIGNED_OWNER, cwd: '/data/user-workspaces/u2/x' }, user), false)
|
||||
assert.equal(jobVisibleToIdentity({ ownerEmpNo: UNASSIGNED_OWNER }, user), false)
|
||||
assert.equal(jobVisibleToIdentity({ ownerEmpNo: UNASSIGNED_OWNER, cwd: '/data/user-workspaces/u1/x' }, user), false)
|
||||
assert.equal(jobVisibleToIdentity({ ownerEmpNo: UNASSIGNED_OWNER }, admin), true)
|
||||
assert.equal(canViewAllJobs(admin), true)
|
||||
})
|
||||
|
|
@ -84,7 +84,7 @@ test('claimUnassignedForViewer claims by session owner or user-workspaces cwd',
|
|||
{ id: 'c', ownerEmpNo: UNASSIGNED_OWNER, cwd: '/data/user-workspaces/u2/proj' },
|
||||
{ id: 'd', ownerEmpNo: 'u2', cwd: '/data/user-workspaces/u1/x' },
|
||||
{ id: 'e', ownerEmpNo: UNASSIGNED_OWNER, origin: { kind: 'im', peer: { botId: 'b' } } },
|
||||
{ id: 'f', ownerEmpNo: UNASSIGNED_OWNER, origin: { kind: 'web', sessionId: 'foreign' } },
|
||||
{ id: 'f', ownerEmpNo: UNASSIGNED_OWNER, origin: { kind: 'web', sessionId: 'orphan' } },
|
||||
],
|
||||
}
|
||||
const { changed, state: next } = claimUnassignedForViewer(state, user, {
|
||||
|
|
@ -97,9 +97,9 @@ test('claimUnassignedForViewer claims by session owner or user-workspaces cwd',
|
|||
assert.equal(changed, true)
|
||||
assert.equal(next.jobs[0].ownerEmpNo, 'u1')
|
||||
assert.equal(next.jobs[1].ownerEmpNo, 'u1')
|
||||
// Foreign user-workspaces path must not be stolen.
|
||||
assert.equal(next.jobs[2].ownerEmpNo, UNASSIGNED_OWNER)
|
||||
assert.equal(next.jobs[3].ownerEmpNo, 'u2')
|
||||
assert.equal(next.jobs[4].ownerEmpNo, UNASSIGNED_OWNER)
|
||||
// Unknown session owner: leave unassigned for admin-only visibility.
|
||||
assert.equal(next.jobs[5].ownerEmpNo, UNASSIGNED_OWNER)
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue