Split employee devices from DeviceConnection

viewer.enrolledDevices shared DeviceConnection with the admin
org list, so totalCount had to authorize with both
employee-device:list and device:list. Mirror
EmployeeDocumentConnection: a dedicated EmployeeDeviceConnection
without totalCount, and keep DeviceConnection.totalCount for
the org fleet only. Cover assumed-session device:get IDOR in e2e.

Signed-off-by: Ludovic Vielle <ludovic@probo.com>
This commit is contained in:
Ludovic Vielle
2026-07-21 15:06:12 +02:00
parent 85864a580c
commit 6cac6a8775
7 changed files with 67 additions and 27 deletions

View File

@@ -184,7 +184,7 @@ func (r *viewerResolver) ApprovableDocument(ctx context.Context, obj *types.View
}
// EnrolledDevices is the resolver for the enrolledDevices field.
func (r *viewerResolver) EnrolledDevices(ctx context.Context, obj *types.Viewer, organizationID gid.GID, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DeviceOrderBy) (*types.DeviceConnection, error) {
func (r *viewerResolver) EnrolledDevices(ctx context.Context, obj *types.Viewer, organizationID gid.GID, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DeviceOrderBy) (*types.EmployeeDeviceConnection, error) {
scope, err := r.authorize(ctx, organizationID, itam.ActionEmployeeDeviceList)
if err != nil {
return nil, err
@@ -228,7 +228,7 @@ func (r *viewerResolver) EnrolledDevices(ctx context.Context, obj *types.Viewer,
return nil, gqlutils.Internal(ctx)
}
return types.NewOwnedDeviceConnection(devicesPage, r, organizationID, profile.ID), nil
return types.NewEmployeeDeviceConnection(devicesPage), nil
}
// EnrolledDevice is the resolver for the enrolledDevice field.