3 const common
= require('./common');
4 const Enum
= require('./enum');
5 const { Chores: BaseChores
} = require('@squeep/chores');
6 const _fileScope
= common
.fileScope(__filename
);
9 * Wrangle periodic tasks what need doing.
12 class Chores
extends BaseChores
{
13 constructor(logger
, db
, queuePublisher
, options
) {
15 this.options
= options
;
17 this.queuePublisher
= queuePublisher
;
19 this.establishChore(Enum
.Chore
.CleanTokens
, this.cleanTokens
.bind(this), options
?.chores
?.tokenCleanupMs
);
20 this.establishChore(Enum
.Chore
.CleanScopes
, this.cleanScopes
.bind(this), options
?.chores
?.scopeCleanupMs
);
21 this.establishChore(Enum
.Chore
.PublishTickets
, this.publishTickets
.bind(this), options
?.chores
?.publishTicketsMs
);
25 * Attempt to remove tokens which are expired or otherwise no longer valid.
26 * @param {number} atLeastMsSinceLast minimum clean period
28 async
cleanTokens(atLeastMsSinceLast
= this.options
?.chores
?.tokenCleanupMs
|| 0) {
29 const _scope
= _fileScope('cleanTokens');
30 this.logger
.debug(_scope
, 'called', { atLeastMsSinceLast
});
34 await
this.db
.context(async (dbCtx
) => {
35 const codeValidityTimeoutSeconds
= Math
.ceil(this.options
.manager
.codeValidityTimeoutMs
/ 1000);
36 tokensCleaned
= await
this.db
.tokenCleanup(dbCtx
, codeValidityTimeoutSeconds
, atLeastMsSinceLast
);
39 this.logger
.info(_scope
, 'finished', { tokensCleaned
});
42 this.logger
.error(_scope
, 'failed', { error: e
});
49 * Attempt to remove ephemeral scopes which are no longer referenced by tokens.
50 * @param {number} atLeastMsSinceLast minimum clean period
52 async
cleanScopes(atLeastMsSinceLast
= this.options
?.chores
?.scopeCleanupMs
|| 0) {
53 const _scope
= _fileScope('cleanScopes');
54 this.logger
.debug(_scope
, 'called', { atLeastMsSinceLast
});
58 await
this.db
.context(async (dbCtx
) => {
59 scopesCleaned
= await
this.db
.scopeCleanup(dbCtx
, atLeastMsSinceLast
);
62 this.logger
.info(_scope
, 'finished', { scopesCleaned
});
65 this.logger
.error(_scope
, 'failed', { error: e
});
72 * Attempt to deliver any redeemed but un-delivered ticket tokens.
74 async
publishTickets() {
75 const _scope
= _fileScope('publishTickets');
76 this.logger
.debug(_scope
, 'called');
79 const queueName
= this.options
.queues
.ticketRedeemedName
;
80 await
this.db
.context(async (dbCtx
) => {
81 const ticketTokens
= await
this.db
.ticketTokenGetUnpublished(dbCtx
);
82 for await (const data
of ticketTokens
) {
84 const result
= await
this.queuePublisher
.publish(queueName
, data
);
85 this.logger
.info(_scope
, 'published ticket token', { queueName
, result
, ...data
});
86 const redeemedData
= common
.pick(data
, ['resource', 'subject', 'iss', 'ticket', 'token']);
87 await
this.db
.ticketTokenPublished(dbCtx
, redeemedData
);
89 this.logger
.error(_scope
, 'publish failed', { error: e
, data
});
94 this.logger
.error(_scope
, 'failed', { error: e
});
100 module
.exports
= Chores
;