@@ -21,17 +21,22 @@ import { EmailService } from '../../email/email/email.service.js';
2121import { escapeHtml } from '../../email/utils/escape-html.util.js' ;
2222import { UserEntity } from '../../user/user.entity.js' ;
2323import { TableActionEntity } from './table-action.entity.js' ;
24+ import { describeTableActionActor , UserInfoMessageData } from './utils/describe-table-action-actor.util.js' ;
25+
26+ export type { TableActionActorKind , UserInfoMessageData } from './utils/describe-table-action-actor.util.js' ;
2427
2528export type ActionActivationResult = {
2629 location ?: string ;
2730 receivedOperationResult : OperationResultStatusEnum ;
2831 receivedPrimaryKeysObj : Array < Record < string , unknown > > ;
2932} ;
3033
31- export type UserInfoMessageData = {
32- userId : string ;
33- email : string ;
34- userName : string | null ;
34+ // A generated-site end-user acting through universal-backend (plan 37): the users-row primary key
35+ // carried by their token (`uid`, null for a pre-uid grace token) and the address they registered
36+ // with when the site passed it along. Neither is a RocketAdmin identity.
37+ export type SitenovaVisitorActor = {
38+ visitorId : string | null ;
39+ email : string | null ;
3540} ;
3641
3742@Injectable ( )
@@ -62,10 +67,59 @@ export class TableActionActivationService {
6267 ) ;
6368 }
6469 const userInfoMessageData : UserInfoMessageData = {
70+ actorKind : 'rocketadmin_user' ,
6571 userId,
6672 email : foundUser . email ,
6773 userName : foundUser . name ,
74+ visitorId : null ,
6875 } ;
76+ return await this . activateTableActionAs (
77+ tableAction ,
78+ foundConnection ,
79+ request_body ,
80+ userInfoMessageData ,
81+ tableName ,
82+ triggerOperation ,
83+ ) ;
84+ }
85+
86+ // Same dispatch as activateTableAction, for an operation performed by a generated-site visitor
87+ // rather than a RocketAdmin user (plan 37). There is no account to look up: the actor is
88+ // described from what universal-backend forwarded, and the HTTP payload / Slack / email say so
89+ // explicitly instead of borrowing the connection owner's identity.
90+ public async activateTableActionForVisitor (
91+ tableAction : TableActionEntity ,
92+ foundConnection : ConnectionEntity ,
93+ request_body : Array < Record < string , unknown > > ,
94+ visitor : SitenovaVisitorActor ,
95+ tableName : string ,
96+ triggerOperation : TableActionEventEnum ,
97+ ) : Promise < ActionActivationResult > {
98+ const userInfoMessageData : UserInfoMessageData = {
99+ actorKind : 'sitenova_visitor' ,
100+ userId : null ,
101+ email : visitor . email ,
102+ userName : null ,
103+ visitorId : visitor . visitorId ,
104+ } ;
105+ return await this . activateTableActionAs (
106+ tableAction ,
107+ foundConnection ,
108+ request_body ,
109+ userInfoMessageData ,
110+ tableName ,
111+ triggerOperation ,
112+ ) ;
113+ }
114+
115+ private async activateTableActionAs (
116+ tableAction : TableActionEntity ,
117+ foundConnection : ConnectionEntity ,
118+ request_body : Array < Record < string , unknown > > ,
119+ userInfoMessageData : UserInfoMessageData ,
120+ tableName : string ,
121+ triggerOperation : TableActionEventEnum ,
122+ ) : Promise < ActionActivationResult > {
69123 switch ( tableAction . method ) {
70124 case TableActionMethodEnum . URL :
71125 return await this . activateHttpTableAction (
@@ -190,8 +244,14 @@ export class TableActionActivationService {
190244 ) ;
191245
192246 const dateString = new Date ( ) . toISOString ( ) ;
247+ // Wire contract of URL actions (consumers verify it with the Rocketadmin-Signature HMAC).
248+ // $$_raUserId is the historical field and stays a string for RocketAdmin users; it is null when
249+ // a generated-site visitor acted (plan 37) — such events never fired before, so no existing
250+ // consumer saw a null there. $$_triggeredBy / $$_visitorId are additive.
193251 const actionRequestBody = JSON . stringify ( {
194252 $$_raUserId : userId ,
253+ $$_triggeredBy : userInfo . actorKind ,
254+ $$_visitorId : userInfo . visitorId ,
195255 primaryKeys : primaryKeyValuesArray ,
196256 $$_date : dateString ,
197257 $$_actionId : tableAction . id ,
@@ -380,7 +440,6 @@ export class TableActionActivationService {
380440 tableName : string ,
381441 primaryKeyValuesArray : Array < Record < string , unknown > > ,
382442 ) : string {
383- const { email, userId, userName } = userInfo ;
384443 const action =
385444 triggerOperation === TableActionEventEnum . ADD_ROW
386445 ? 'added a row'
@@ -390,7 +449,7 @@ export class TableActionActivationService {
390449 ? 'deleted a row'
391450 : 'performed an action' ;
392451 primaryKeyValuesArray = this . escapePrimaryKeyValuesArray ( primaryKeyValuesArray ) ;
393- const textContent = `${ userName ? escapeHtml ( userName ) : 'User' } (email: ${ email } , user id: ${ userId } ) has ${ action } in the table "${ escapeHtml ( tableName ) } ".` ;
452+ const textContent = `${ describeTableActionActor ( userInfo ) } has ${ action } in the table "${ escapeHtml ( tableName ) } ".` ;
394453 return `${ textContent } Primary Keys: ${ JSON . stringify ( primaryKeyValuesArray ) } ` ;
395454 }
396455}
0 commit comments