fix(provenance): address #143 review — page-stamp tests, confine is_agent, doc fixes
Resolves the open items from the latest PR #143 code review: - test(page): cover the four agentSourceFields stamp sites (create, update, movePage, movePageToSpace) with agent + normal-user payload assertions; add findById({ includeIsAgent: true }) wiring guards to the JWT and collab auth-seam specs so a future drop of the option is caught. - fix(privacy): drop `isAgent` from UserRepo.baseFields and gate it behind a new opt-in `findById({ includeIsAgent })`, requested only by the two auth seams that derive provenance — stops the flag leaking via the workspace member list and generic user payloads. - docs: correct the agentSourceFields JSDoc and the two UPDATE-site comments to distinguish INSERT (omitted column → DB default 'user') from UPDATE (omitted column → existing value kept, Kysely writes only present keys). - style(page): collapse three stray double blank lines left by an earlier edit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -36,9 +36,6 @@ export class UserRepo {
|
||||
'updatedAt',
|
||||
'deletedAt',
|
||||
'hasGeneratedPassword',
|
||||
// AI agent identity flag — needed by the JWT strategy to derive a
|
||||
// non-spoofable 'agent' provenance from the signed server-side identity.
|
||||
'isAgent',
|
||||
];
|
||||
|
||||
async findById(
|
||||
@@ -48,6 +45,12 @@ export class UserRepo {
|
||||
includePassword?: boolean;
|
||||
includeUserMfa?: boolean;
|
||||
includeScimExternalId?: boolean;
|
||||
// Opt-in: `isAgent` is internal provenance state, not part of the generic
|
||||
// user payload. Keeping it out of `baseFields` stops it from leaking into
|
||||
// the workspace member list / `/users/me` (an enumeration leak). Only the
|
||||
// JWT + collab auth seams opt in, because they derive a non-spoofable
|
||||
// 'agent' provenance from the signed server-side identity.
|
||||
includeIsAgent?: boolean;
|
||||
trx?: KyselyTransaction;
|
||||
},
|
||||
): Promise<User> {
|
||||
@@ -58,6 +61,7 @@ export class UserRepo {
|
||||
.$if(opts?.includePassword, (qb) => qb.select('password'))
|
||||
.$if(opts?.includeUserMfa, (qb) => qb.select(this.withUserMfa))
|
||||
.$if(opts?.includeScimExternalId, (qb) => qb.select('scimExternalId'))
|
||||
.$if(opts?.includeIsAgent, (qb) => qb.select('isAgent'))
|
||||
.where('id', '=', userId)
|
||||
.where('workspaceId', '=', workspaceId)
|
||||
.executeTakeFirst();
|
||||
|
||||
Reference in New Issue
Block a user