@solidxai/core 0.1.6-beta.3 → 0.1.6-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/seeders/seed-data/solid-core-metadata.json +73 -3
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +44 -21
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/queues/database-subscriber.service.d.ts +4 -2
- package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/database-subscriber.service.js +9 -1
- package/dist/services/queues/database-subscriber.service.js.map +1 -1
- package/dist/services/queues/publisher-factory.service.d.ts.map +1 -1
- package/dist/services/queues/publisher-factory.service.js +4 -6
- package/dist/services/queues/publisher-factory.service.js.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.d.ts +4 -2
- package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.js +9 -1
- package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
- package/package.json +1 -1
- package/src/seeders/seed-data/solid-core-metadata.json +73 -3
- package/src/services/authentication.service.ts +46 -24
- package/src/services/queues/database-subscriber.service.ts +12 -1
- package/src/services/queues/publisher-factory.service.ts +8 -6
- package/src/services/queues/rabbitmq-subscriber.service.ts +12 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database-subscriber.service.js","sourceRoot":"","sources":["../../../src/services/queues/database-subscriber.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger, OnModuleInit } from '@nestjs/common';\nimport { QueuesModuleOptions } from \"../../interfaces\";\nimport { QueueMessage, QueueSubscriber } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\nimport { PollerService } from '../poller.service';\nimport { buildNamespacedQueueName } from './common';\n\nexport abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscriber<T> {\n private readonly logger = new Logger(DatabaseSubscriber.name);\n private readonly url: string;\n private readonly serviceRole: string;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n protected readonly poller: PollerService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n // this.logger.debug(`DatabaseSubscriber instance created with options: ${JSON.stringify(this.options())}`);\n }\n\n abstract subscribe(message: QueueMessage<T>);\n\n abstract options(): QueuesModuleOptions;\n\n private async processNext(queueName: string) {\n // this.logger.debug(`#### DatabaseSubscriber processing next message from queue: ${queueName}`);\n const job = await this.mqMessageService.lockNextPendingMessage(queueName);\n if (!job) {\n return;\n }\n\n const messageContentString = job.input.toString();\n // this.logger.debug(`DatabaseSubscriber Received raw message: ${messageContentString}`);\n\n let message: QueueMessage<T> = null;\n\n try {\n message = JSON.parse(messageContentString) as QueueMessage<T>;\n\n // this is the first time we are receiving the message so we set the currentRetry to 0\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n if (!message.currentRetry) message.currentRetry = 0;\n\n await this.processMessage(message);\n }\n catch (error) {\n this.logger.error(`Error processing message: ${error.message}`);\n\n // if an error occurs then if retryCount is set we start retrying. \n if (message) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms`);\n setTimeout(() => {\n this.retryMessage(message);\n }, message.retryInterval);\n } else {\n // Discard the message after max retries\n await this.updateStatusInDatabase('failed', message, error.message, '');\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n }\n }\n }\n // this.logger.debug(`#### DatabaseSubscriber finished processing message from queue: ${queueName}`);\n }\n\n async onModuleInit(): Promise<void> {\n // Not using SettingService here as that will necessitate all implementors of DatabaseSubscriber to also inject SettingService which is not ideal. \n // Instead we directly read the environment variables here.\n const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'database';\n const solidCliRunning = process.env.SOLID_CLI_RUNNING || \"false\";\n const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();\n\n // we will start subscriber only if the current service role is subscriber. \n if (['both', 'subscriber'].includes(this.serviceRole) && defaultBroker === 'database' && solidCliRunning === \"false\") {\n const options = this.options();\n const queueName = options.queueName;\n\n if (queueNameRegex && queueNameRegex !== \"all\") {\n try {\n const regex = new RegExp(queueNameRegex);\n if (!regex.test(queueName)) {\n this.logger.log(`DatabaseSubscriber for queue ${queueName} is disabled because it does not match QUEUES_QUEUE_NAME_REGEX_TO_ENABLE=${queueNameRegex}`);\n return;\n }\n } catch (error) {\n this.logger.error(`Invalid QUEUES_QUEUE_NAME_REGEX_TO_ENABLE regex \"${queueNameRegex}\". Subscriber for queue ${queueName} will not start.`);\n return;\n }\n }\n\n const namespacedQueueName = buildNamespacedQueueName(queueName);\n this.poller.start(namespacedQueueName, (q) => this.processNext(q), {\n baseDelayMs: 1000,\n maxDelayMs: 30_000,\n timeoutPerIterationMs: 5 * 60_000,\n jitter: true,\n });\n\n this.logger.log(`DatabaseSubscriber ready to consume messages: ${JSON.stringify(this.options())}`);\n }\n }\n\n onModuleDestroy() {\n const options = this.options();\n const queueName = options.queueName;\n const namespacedQueueName = buildNamespacedQueueName(queueName);\n this.poller.stop(namespacedQueueName);\n }\n\n /**\n * Abstract method for message processing logic.\n */\n protected async processMessage(message: QueueMessage<T>): Promise<void> {\n await this.updateStatusInDatabase('started', message);\n\n // Capture the results of handling the task.\n const result = await this.subscribe(message);\n\n // TODO: Update the database to indicate that the task is finished.\n await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');\n }\n\n /**\n * Retry the message by invoking the processing logic again.\n */\n private async retryMessage(message: QueueMessage<T>) {\n try {\n await this.processMessage(message);\n } catch (error) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms: ${error.message}`);\n setTimeout(() => {\n this.retryMessage(message);\n }, message.retryInterval);\n } else {\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n\n // TODO: Store the error in the database and update the status accordingly.\n await this.updateStatusInDatabase('failed', message, error.message, '');\n\n }\n }\n }\n\n private async updateStatusInDatabase(stage: string, message: QueueMessage<T>, error: string = '', result: string = '') {\n try {\n this.logger.debug(`Updating message status in database: ${stage} for messageId: ${message.messageId}`);\n\n // 1. resolve the queue first\n const mqMessage = await this.mqMessageService.repo.findOne({\n where: {\n messageId: message.messageId,\n }\n });\n\n if (mqMessage) {\n this.logger.debug(`Found message in database: ${JSON.stringify(mqMessage.messageId)}`);\n this.logger.debug(`Updating message status in database: ${stage} for messageId: ${mqMessage.id}`);\n\n const updatedFields = {\n stage: stage\n };\n if (stage === 'failed' || stage === 'succeeded') {\n updatedFields['finishedAt'] = new Date();\n updatedFields['elapsedMillis'] = updatedFields['finishedAt'].getTime() - mqMessage.startedAt.getTime();\n }\n if (stage === 'succeeded') {\n updatedFields['output'] = result;\n }\n if (stage === 'failed') {\n updatedFields['error'] = error;\n }\n await this.mqMessageService.repo.update(mqMessage.id, updatedFields);\n this.logger.debug(`Message status updated to ${stage} for messageId: ${mqMessage.id}`);\n }\n }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"database-subscriber.service.js","sourceRoot":"","sources":["../../../src/services/queues/database-subscriber.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger, OnModuleInit } from '@nestjs/common';\nimport { QueuesModuleOptions } from \"../../interfaces\";\nimport { QueueMessage, QueueSubscriber } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\nimport { PollerService } from '../poller.service';\nimport { buildNamespacedQueueName } from './common';\n\nexport abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscriber<T> {\n private _loggerInstance?: Logger;\n private readonly url: string;\n private readonly serviceRole: string;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n protected readonly poller: PollerService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n // this.logger.debug(`DatabaseSubscriber instance created with options: ${JSON.stringify(this.options())}`);\n }\n\n protected get loggerContext(): string {\n return this.constructor.name;\n }\n\n protected get logger(): Logger {\n if (!this._loggerInstance) {\n this._loggerInstance = new Logger(this.loggerContext);\n }\n return this._loggerInstance;\n }\n\n abstract subscribe(message: QueueMessage<T>);\n\n abstract options(): QueuesModuleOptions;\n\n private async processNext(queueName: string) {\n // this.logger.debug(`#### DatabaseSubscriber processing next message from queue: ${queueName}`);\n const job = await this.mqMessageService.lockNextPendingMessage(queueName);\n if (!job) {\n return;\n }\n\n const messageContentString = job.input.toString();\n // this.logger.debug(`DatabaseSubscriber Received raw message: ${messageContentString}`);\n\n let message: QueueMessage<T> = null;\n\n try {\n message = JSON.parse(messageContentString) as QueueMessage<T>;\n\n // this is the first time we are receiving the message so we set the currentRetry to 0\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n if (!message.currentRetry) message.currentRetry = 0;\n\n await this.processMessage(message);\n }\n catch (error) {\n this.logger.error(`Error processing message: ${error.message}`);\n\n // if an error occurs then if retryCount is set we start retrying. \n if (message) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms`);\n setTimeout(() => {\n this.retryMessage(message);\n }, message.retryInterval);\n } else {\n // Discard the message after max retries\n await this.updateStatusInDatabase('failed', message, error.message, '');\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n }\n }\n }\n // this.logger.debug(`#### DatabaseSubscriber finished processing message from queue: ${queueName}`);\n }\n\n async onModuleInit(): Promise<void> {\n // Not using SettingService here as that will necessitate all implementors of DatabaseSubscriber to also inject SettingService which is not ideal. \n // Instead we directly read the environment variables here.\n const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'database';\n const solidCliRunning = process.env.SOLID_CLI_RUNNING || \"false\";\n const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();\n\n // we will start subscriber only if the current service role is subscriber. \n if (['both', 'subscriber'].includes(this.serviceRole) && defaultBroker === 'database' && solidCliRunning === \"false\") {\n const options = this.options();\n const queueName = options.queueName;\n\n if (queueNameRegex && queueNameRegex !== \"all\") {\n try {\n const regex = new RegExp(queueNameRegex);\n if (!regex.test(queueName)) {\n this.logger.log(`DatabaseSubscriber for queue ${queueName} is disabled because it does not match QUEUES_QUEUE_NAME_REGEX_TO_ENABLE=${queueNameRegex}`);\n return;\n }\n } catch (error) {\n this.logger.error(`Invalid QUEUES_QUEUE_NAME_REGEX_TO_ENABLE regex \"${queueNameRegex}\". Subscriber for queue ${queueName} will not start.`);\n return;\n }\n }\n\n const namespacedQueueName = buildNamespacedQueueName(queueName);\n this.poller.start(namespacedQueueName, (q) => this.processNext(q), {\n baseDelayMs: 1000,\n maxDelayMs: 30_000,\n timeoutPerIterationMs: 5 * 60_000,\n jitter: true,\n });\n\n this.logger.log(`DatabaseSubscriber ready to consume messages: ${JSON.stringify(this.options())}`);\n }\n }\n\n onModuleDestroy() {\n const options = this.options();\n const queueName = options.queueName;\n const namespacedQueueName = buildNamespacedQueueName(queueName);\n this.poller.stop(namespacedQueueName);\n }\n\n /**\n * Abstract method for message processing logic.\n */\n protected async processMessage(message: QueueMessage<T>): Promise<void> {\n await this.updateStatusInDatabase('started', message);\n\n // Capture the results of handling the task.\n const result = await this.subscribe(message);\n\n // TODO: Update the database to indicate that the task is finished.\n await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');\n }\n\n /**\n * Retry the message by invoking the processing logic again.\n */\n private async retryMessage(message: QueueMessage<T>) {\n try {\n await this.processMessage(message);\n } catch (error) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms: ${error.message}`);\n setTimeout(() => {\n this.retryMessage(message);\n }, message.retryInterval);\n } else {\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n\n // TODO: Store the error in the database and update the status accordingly.\n await this.updateStatusInDatabase('failed', message, error.message, '');\n\n }\n }\n }\n\n private async updateStatusInDatabase(stage: string, message: QueueMessage<T>, error: string = '', result: string = '') {\n try {\n this.logger.debug(`Updating message status in database: ${stage} for messageId: ${message.messageId}`);\n\n // 1. resolve the queue first\n const mqMessage = await this.mqMessageService.repo.findOne({\n where: {\n messageId: message.messageId,\n }\n });\n\n if (mqMessage) {\n this.logger.debug(`Found message in database: ${JSON.stringify(mqMessage.messageId)}`);\n this.logger.debug(`Updating message status in database: ${stage} for messageId: ${mqMessage.id}`);\n\n const updatedFields = {\n stage: stage\n };\n if (stage === 'failed' || stage === 'succeeded') {\n updatedFields['finishedAt'] = new Date();\n updatedFields['elapsedMillis'] = updatedFields['finishedAt'].getTime() - mqMessage.startedAt.getTime();\n }\n if (stage === 'succeeded') {\n updatedFields['output'] = result;\n }\n if (stage === 'failed') {\n updatedFields['error'] = error;\n }\n await this.mqMessageService.repo.update(mqMessage.id, updatedFields);\n this.logger.debug(`Message status updated to ${stage} for messageId: ${mqMessage.id}`);\n }\n }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publisher-factory.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/publisher-factory.service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAkB,MAAM,mBAAmB,CAAC;AAEjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,qBACa,gBAAgB,CAAC,CAAC;IAKvB,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAJ9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;gBAIvC,yBAAyB,EAAE,sBAAsB;IAIhE,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"publisher-factory.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/publisher-factory.service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAkB,MAAM,mBAAmB,CAAC;AAEjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,qBACa,gBAAgB,CAAC,CAAC;IAKvB,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAJ9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;gBAIvC,yBAAyB,EAAE,sBAAsB;IAIhE,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAyBxG"}
|
|
@@ -28,12 +28,10 @@ let PublisherFactory = PublisherFactory_1 = class PublisherFactory {
|
|
|
28
28
|
let resolvedPublisherName = `${publisherName}${(0, strings_1.classify)(defaultBrokerToUse)}`;
|
|
29
29
|
let actualPublisherToUse = this.solidIntrospectionService.getProvider(resolvedPublisherName);
|
|
30
30
|
if (!actualPublisherToUse) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
}
|
|
31
|
+
actualPublisherToUse = this.solidIntrospectionService.getProvider(publisherName);
|
|
32
|
+
}
|
|
33
|
+
if (!actualPublisherToUse) {
|
|
34
|
+
throw new Error(`Unable to locate publisher with name ${resolvedPublisherName}`);
|
|
37
35
|
}
|
|
38
36
|
const typedActualPublisher = actualPublisherToUse.instance;
|
|
39
37
|
this.logger.debug(`Resolved publisher with name ${actualPublisherToUse.name}, and with options: ${JSON.stringify(typedActualPublisher.options())}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publisher-factory.service.js","sourceRoot":"","sources":["../../../src/services/queues/publisher-factory.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAA4D;AAC5D,2CAA4C;AAG5C,oEAAkE;AAClE,0EAAqE;AAI9D,IAAM,gBAAgB,wBAAtB,MAAM,gBAAgB;IAGzB,YAEI,yBAAkE;QAAjD,8BAAyB,GAAzB,yBAAyB,CAAwB;QAJrD,WAAM,GAAG,IAAI,eAAM,CAAC,kBAAgB,CAAC,IAAI,CAAC,CAAC;IAM5D,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAwB,EAAE,aAAqB,EAAE,WAAoB;QAC/E,IAAI,kBAAkB,GAAG,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,UAAU,CAAC;QACxF,IAAI,qBAAqB,GAAG,GAAG,aAAa,GAAG,IAAA,kBAAQ,EAAC,kBAAkB,CAAC,EAAE,CAAC;QAG9E,IAAI,oBAAoB,GAAG,IAAI,CAAC,yBAAyB,CAAC,WAAW,CAAC,qBAAqB,CAAC,CAAC;QAC7F,IAAI,CAAC,oBAAoB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"publisher-factory.service.js","sourceRoot":"","sources":["../../../src/services/queues/publisher-factory.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAA4D;AAC5D,2CAA4C;AAG5C,oEAAkE;AAClE,0EAAqE;AAI9D,IAAM,gBAAgB,wBAAtB,MAAM,gBAAgB;IAGzB,YAEI,yBAAkE;QAAjD,8BAAyB,GAAzB,yBAAyB,CAAwB;QAJrD,WAAM,GAAG,IAAI,eAAM,CAAC,kBAAgB,CAAC,IAAI,CAAC,CAAC;IAM5D,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAwB,EAAE,aAAqB,EAAE,WAAoB;QAC/E,IAAI,kBAAkB,GAAG,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,UAAU,CAAC;QACxF,IAAI,qBAAqB,GAAG,GAAG,aAAa,GAAG,IAAA,kBAAQ,EAAC,kBAAkB,CAAC,EAAE,CAAC;QAG9E,IAAI,oBAAoB,GAAG,IAAI,CAAC,yBAAyB,CAAC,WAAW,CAAC,qBAAqB,CAAC,CAAC;QAC7F,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAExB,oBAAoB,GAAG,IAAI,CAAC,yBAAyB,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QAMrF,CAAC;QACD,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,wCAAwC,qBAAqB,EAAE,CAAC,CAAC;QACrF,CAAC;QAGD,MAAM,oBAAoB,GAAsB,oBAAoB,CAAC,QAAQ,CAAC;QAC9E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,oBAAoB,CAAC,IAAI,uBAAuB,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QAEpJ,OAAO,oBAAoB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;CACJ,CAAA;AAlCY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;IAKJ,WAAA,IAAA,eAAM,EAAC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,iDAAsB,CAAC,CAAC,CAAA;qCACL,iDAAsB;GAL7D,gBAAgB,CAkC5B","sourcesContent":["import { forwardRef, Inject, Logger } from '@nestjs/common';\nimport { Injectable } from '@nestjs/common';\n\nimport { QueueMessage, QueuePublisher } from 'src/interfaces/mq';\nimport { classify } from '@angular-devkit/core/src/utils/strings';\nimport { SolidIntrospectService } from '../solid-introspect.service';\n\n\n@Injectable()\nexport class PublisherFactory<T> {\n private readonly logger = new Logger(PublisherFactory.name);\n\n constructor(\n @Inject(forwardRef(() => SolidIntrospectService))\n private readonly solidIntrospectionService: SolidIntrospectService\n ) {\n }\n\n async publish(message: QueueMessage<T>, publisherName: string, brokerToUse?: string): Promise<string> {\n let defaultBrokerToUse = brokerToUse || process.env.QUEUES_DEFAULT_BROKER || \"database\";\n let resolvedPublisherName = `${publisherName}${classify(defaultBrokerToUse)}`;\n\n // Register all ISolidDatabaseModules implementations\n let actualPublisherToUse = this.solidIntrospectionService.getProvider(resolvedPublisherName);\n if (!actualPublisherToUse) {\n // Relaxed extra check in place to make sure we do not have to refactor old publishers or publishers named without the ____RabbitMq or ____Database convention\n actualPublisherToUse = this.solidIntrospectionService.getProvider(publisherName);\n\n // Extra check in place to make sure we do not have to refactor old publishers which have been created earlier. \n // if (defaultBrokerToUse === 'rabbitmq') {\n // actualPublisherToUse = this.solidIntrospectionService.getProvider(publisherName);\n // }\n }\n if (!actualPublisherToUse) {\n throw new Error(`Unable to locate publisher with name ${resolvedPublisherName}`);\n }\n\n // type safe\n const typedActualPublisher: QueuePublisher<T> = actualPublisherToUse.instance;\n this.logger.debug(`Resolved publisher with name ${actualPublisherToUse.name}, and with options: ${JSON.stringify(typedActualPublisher.options())}`);\n\n return typedActualPublisher.publish(message);\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { OnModuleInit } from '@nestjs/common';
|
|
1
|
+
import { Logger, OnModuleInit } from '@nestjs/common';
|
|
2
2
|
import * as amqp from 'amqplib';
|
|
3
3
|
import { QueuesModuleOptions } from "../../interfaces";
|
|
4
4
|
import { QueueMessage, QueueSubscriber } from '../../interfaces/mq';
|
|
@@ -7,7 +7,7 @@ import { MqMessageService } from '../mq-message.service';
|
|
|
7
7
|
export declare abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscriber<T> {
|
|
8
8
|
protected readonly mqMessageService: MqMessageService;
|
|
9
9
|
protected readonly mqMessageQueueService: MqMessageQueueService;
|
|
10
|
-
private
|
|
10
|
+
private _loggerInstance?;
|
|
11
11
|
private readonly url;
|
|
12
12
|
private readonly serviceRole;
|
|
13
13
|
private connection;
|
|
@@ -17,6 +17,8 @@ export declare abstract class RabbitMqSubscriber<T> implements OnModuleInit, Que
|
|
|
17
17
|
private reconnectAttempt;
|
|
18
18
|
private stopping;
|
|
19
19
|
constructor(mqMessageService: MqMessageService, mqMessageQueueService: MqMessageQueueService);
|
|
20
|
+
protected get loggerContext(): string;
|
|
21
|
+
protected get logger(): Logger;
|
|
20
22
|
abstract subscribe(message: QueueMessage<T>): any;
|
|
21
23
|
abstract options(): QueuesModuleOptions;
|
|
22
24
|
establishConnection(): Promise<amqp.Connection>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rabbitmq-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/rabbitmq-subscriber.service.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"rabbitmq-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/rabbitmq-subscriber.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAIzD,8BAAsB,kBAAkB,CAAC,CAAC,CAAE,YAAW,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAWvE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IAAE,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IAVlI,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,QAAQ,CAAS;gBAEM,gBAAgB,EAAE,gBAAgB,EAAqB,qBAAqB,EAAE,qBAAqB;IAYlI,SAAS,KAAK,aAAa,IAAI,MAAM,CAEpC;IAED,SAAS,KAAK,MAAM,IAAI,MAAM,CAK7B;IAED,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3C,QAAQ,CAAC,OAAO,IAAI,mBAAmB;IAEjC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;IAsB/C,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;YAqCrB,iBAAiB;YA0GjB,qBAAqB;YA8BrB,oBAAoB;IAclC,OAAO,CAAC,gBAAgB;YAWV,aAAa;YAkBb,OAAO;IAkCrB,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,OAAO;cAWC,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,UAAU,KAAA,EAAE,OAAO,KAAA,GAAG,OAAO,CAAC,IAAI,CAAC;YAc9E,sBAAsB;CAkCvC"}
|
|
@@ -41,7 +41,6 @@ class RabbitMqSubscriber {
|
|
|
41
41
|
constructor(mqMessageService, mqMessageQueueService) {
|
|
42
42
|
this.mqMessageService = mqMessageService;
|
|
43
43
|
this.mqMessageQueueService = mqMessageQueueService;
|
|
44
|
-
this.logger = new common_1.Logger(RabbitMqSubscriber.name);
|
|
45
44
|
this.connection = null;
|
|
46
45
|
this.channel = null;
|
|
47
46
|
this.consumerTag = null;
|
|
@@ -57,6 +56,15 @@ class RabbitMqSubscriber {
|
|
|
57
56
|
this.logger.debug('Queue service Role is not defined in the environment variables');
|
|
58
57
|
}
|
|
59
58
|
}
|
|
59
|
+
get loggerContext() {
|
|
60
|
+
return this.constructor.name;
|
|
61
|
+
}
|
|
62
|
+
get logger() {
|
|
63
|
+
if (!this._loggerInstance) {
|
|
64
|
+
this._loggerInstance = new common_1.Logger(this.loggerContext);
|
|
65
|
+
}
|
|
66
|
+
return this._loggerInstance;
|
|
67
|
+
}
|
|
60
68
|
async establishConnection() {
|
|
61
69
|
const url = new URL(this.url);
|
|
62
70
|
const connection = await amqp.connect({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rabbitmq-subscriber.service.js","sourceRoot":"","sources":["../../../src/services/queues/rabbitmq-subscriber.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger, OnModuleInit } from '@nestjs/common';\nimport * as amqp from 'amqplib';\nimport { QueuesModuleOptions } from \"../../interfaces\";\nimport { QueueMessage, QueueSubscriber } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\nimport { buildNamespacedQueueName } from './common';\n\n\nexport abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscriber<T> { // TODO This can be made a generic type for better type visibility\n private readonly logger = new Logger(RabbitMqSubscriber.name);\n private readonly url: string;\n private readonly serviceRole: string;\n private connection: amqp.Connection | null = null;\n private channel: amqp.Channel | null = null;\n private consumerTag: string | null = null;\n private reconnectPromise: Promise<void> | null = null;\n private reconnectAttempt = 0;\n private stopping = false;\n\n constructor(protected readonly mqMessageService: MqMessageService, protected readonly mqMessageQueueService: MqMessageQueueService) {\n this.url = process.env.QUEUES_RABBIT_MQ_URL;\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.url) {\n this.logger.debug('RabbitMqPublisher url is not defined in the environment variables');\n }\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n // this.logger.debug(`RabbitMqSubscriber instance created with options: ${JSON.stringify(this.options())} and url: ${this.url}`);\n }\n\n abstract subscribe(message: QueueMessage<T>);\n\n abstract options(): QueuesModuleOptions;\n\n async establishConnection(): Promise<amqp.Connection> {\n\n const url = new URL(this.url);\n\n // this.logger.debug(`user: ${url.username}`);\n // // just for local debug, don’t log in prod\n // this.logger.debug(`pass: ${url.password}`);\n // this.logger.debug(`path (vhost): ${url.pathname}`);\n\n const connection = await amqp.connect({\n protocol: url.protocol.replace(':', ''),\n hostname: url.hostname,\n port: parseInt(url.port),\n username: url.username,\n password: decodeURIComponent(url.password),\n frameMax: 131072,\n heartbeat: 30,\n });\n\n return connection\n }\n\n async onModuleInit(): Promise<void> {\n // Not using SettingService here as that will necessitate all implementors of RabbitMqSubscriber to also inject SettingService which is not ideal. \n // Instead we directly read the environment variables here.\n const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'rabbitmq';\n const solidCliRunning = process.env.SOLID_CLI_RUNNING || \"false\";\n const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();\n\n // we will start subscriber only if the current service role is subscriber. \n if (this.url && ['both', 'subscriber'].includes(this.serviceRole) && solidCliRunning === \"false\" && defaultBroker === 'rabbitmq') {\n const options = this.options();\n const queueName = options.queueName;\n\n if (queueNameRegex && queueNameRegex !== \"all\") {\n try {\n const regex = new RegExp(queueNameRegex);\n if (!regex.test(queueName)) {\n this.logger.log(`RabbitMqSubscriber for queue ${queueName} is disabled because it does not match QUEUES_QUEUE_NAME_REGEX_TO_ENABLE=${queueNameRegex}`);\n return;\n }\n } catch (error) {\n this.logger.error(`Invalid QUEUES_QUEUE_NAME_REGEX_TO_ENABLE regex \"${queueNameRegex}\". Subscriber for queue ${queueName} will not start.`);\n return;\n }\n }\n\n const namespacedQueueName = buildNamespacedQueueName(queueName);\n try {\n await this.connectAndConsume(namespacedQueueName);\n } catch (err) {\n this.logger.error(`Failed to connect to RabbitMQ for queue ${namespacedQueueName}: ${(err as Error).message}`, (err as Error).stack);\n this.triggerReconnect(namespacedQueueName, 'initial connection failure');\n }\n\n this.logger.log(`RabbitMqSubscriber ready to consume messages: ${JSON.stringify(options)} and url: ${this.url}`);\n }\n }\n\n private async connectAndConsume(queueName: string): Promise<void> {\n await this.cleanup();\n this.logger.log(`RabbitMqSubscriber in connectAndConsume for queue: ${queueName} and url: ${this.url}`);\n\n const options = this.options();\n const prefetch = options.prefetch ?? 1;\n if (prefetch < 1) {\n throw new Error(`RabbitMqSubscriber prefetch must be >= 1 for queue ${queueName}`);\n }\n\n let connection: amqp.Connection;\n try {\n connection = await this.establishConnection();\n } catch (err) {\n this.logger.error(`Failed to connect to RabbitMQ for queue ${queueName}: ${(err as Error).message}`, (err as Error).stack);\n throw err;\n }\n\n this.connection = connection;\n\n connection.on('error', (err) => {\n if (connection !== this.connection) return;\n this.logger.error(`RabbitMqSubscriber connection error for queue ${queueName}: ${(err as Error).message}`);\n });\n\n connection.on('close', () => {\n if (connection !== this.connection) return;\n this.logger.warn(`RabbitMqSubscriber connection closed for queue ${queueName}`);\n this.triggerReconnect(queueName, 'connection closed');\n });\n\n const channel = await connection.createChannel();\n this.channel = channel;\n\n channel.on('error', (err) => {\n if (channel !== this.channel) return;\n this.logger.error(`RabbitMqSubscriber channel error for queue ${queueName}: ${(err as Error).message}`);\n });\n\n channel.on('close', () => {\n if (channel !== this.channel) return;\n this.logger.warn(`RabbitMqSubscriber channel closed for queue ${queueName}`);\n this.triggerReconnect(queueName, 'channel closed');\n });\n\n // Process one message at a time per consumer to avoid parallel work on the same subscriber instance.\n await channel.prefetch(prefetch);\n\n // Use a direct exchange with a stable routing key so retry DLX can route back to the main queue.\n const exchangeName = `${queueName}.exchange`;\n const routingKey = `${queueName}.routing-key`;\n const retryQueue = `${queueName}.retry`;\n const failedQueue = `${queueName}.failed`;\n\n await channel.assertExchange(exchangeName, 'direct', {});\n await channel.assertQueue(queueName, {});\n await channel.bindQueue(queueName, exchangeName, routingKey);\n\n // Retry queue uses DLX to route expired messages back to the main exchange/routing key.\n await channel.assertQueue(retryQueue, {\n arguments: {\n 'x-dead-letter-exchange': exchangeName,\n 'x-dead-letter-routing-key': routingKey,\n }\n });\n\n await channel.assertQueue(failedQueue, {});\n\n const consumeResult = await channel.consume(\n queueName,\n async (rawMessage) => {\n if (!rawMessage) {\n return;\n }\n\n let message: QueueMessage<T> = null;\n\n try {\n const messageContentString = rawMessage.content.toString();\n message = JSON.parse(messageContentString) as QueueMessage<T>;\n this.logger.debug(`rabbitmq subscriber received message with id: ${message.messageId} for queue ${queueName}`);\n } catch (error) {\n this.logger.error(`Invalid JSON message on queue ${queueName}: ${(error as Error).message}`);\n await this.publishToFailedQueue(queueName, rawMessage.content, channel, error);\n channel.ack(rawMessage);\n return;\n }\n\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n if (!message.currentRetry) message.currentRetry = 0;\n\n try {\n await this.processMessage(message, rawMessage, channel);\n } catch (error) {\n await this.handleProcessingError(message, rawMessage, channel, error, queueName);\n }\n },\n // Explicit ack enables reliable processing and retry routing.\n { noAck: false },\n );\n\n this.consumerTag = consumeResult.consumerTag;\n }\n\n // Retry flow: update DB -> increment retry -> send to retry queue with per-message expiration -> ack original.\n private async handleProcessingError(message: QueueMessage<T>, rawMessage: amqp.ConsumeMessage, channel: amqp.Channel, error: any, queueName: string): Promise<void> {\n const errorMessage = (error as Error)?.message || String(error);\n this.logger.error(`Error processing message on queue ${queueName}: ${errorMessage}`);\n\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n const retryQueue = `${queueName}.retry`;\n const payload = Buffer.from(JSON.stringify(message));\n\n // Per-message expiration keeps the message in the retry queue until TTL, then DLX routes it back.\n channel.sendToQueue(retryQueue, payload, {\n expiration: String(message.retryInterval || 1000),\n headers: {\n 'x-error': errorMessage,\n }\n });\n\n channel.ack(rawMessage);\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms on queue ${queueName}`);\n return;\n }\n\n await this.updateStatusInDatabase('failed', message, errorMessage, '');\n channel.ack(rawMessage);\n await this.publishToFailedQueue(queueName, Buffer.from(JSON.stringify(message)), channel, error);\n this.logger.error(`Message failed after ${message.retryCount} attempts on queue ${queueName}: ${errorMessage}`);\n }\n\n private async publishToFailedQueue(queueName: string, payload: Buffer | string, channel: amqp.Channel, error?: any): Promise<void> {\n const failedQueue = `${queueName}.failed`;\n const body = Buffer.isBuffer(payload) ? payload : Buffer.from(payload);\n const errorMessage = (error as Error)?.message || String(error || '');\n\n try {\n channel.sendToQueue(failedQueue, body, errorMessage ? {\n headers: { 'x-error': errorMessage }\n } : undefined);\n } catch (err) {\n this.logger.error(`Failed to publish to failed queue ${failedQueue}: ${(err as Error).message}`);\n }\n }\n\n private triggerReconnect(queueName: string, reason: string) {\n if (this.stopping) return;\n if (this.reconnectPromise) return;\n\n this.reconnectPromise = this.reconnectLoop(queueName, reason)\n .finally(() => {\n this.reconnectPromise = null;\n });\n }\n\n // Reconnect with backoff to avoid hammering the broker during outages.\n private async reconnectLoop(queueName: string, reason: string): Promise<void> {\n this.logger.warn(`RabbitMqSubscriber reconnecting for queue ${queueName}: ${reason}`);\n\n while (!this.stopping) {\n try {\n await this.connectAndConsume(queueName);\n this.reconnectAttempt = 0;\n this.logger.log(`RabbitMqSubscriber reconnected for queue ${queueName}`);\n return;\n } catch (err) {\n this.reconnectAttempt += 1;\n const delay = this.backoff();\n this.logger.warn(`RabbitMqSubscriber reconnect failed for queue ${queueName}; retrying in ${delay}ms`);\n await this.sleep(delay);\n }\n }\n }\n\n private async cleanup(): Promise<void> {\n const channel = this.channel;\n const connection = this.connection;\n const consumerTag = this.consumerTag;\n\n this.channel = null;\n this.connection = null;\n this.consumerTag = null;\n\n if (channel) {\n try {\n if (consumerTag) {\n await channel.cancel(consumerTag);\n }\n } catch (_) {\n // ignore\n }\n\n try {\n await channel.close();\n } catch (_) {\n // ignore\n }\n }\n\n if (connection) {\n try {\n await connection.close();\n } catch (_) {\n // ignore\n }\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n // Exponential backoff with jitter, capped to 30s.\n private backoff(): number {\n const baseMs = 1000;\n const maxMs = 30_000;\n const exp = Math.min(maxMs, baseMs * Math.pow(2, this.reconnectAttempt));\n const jitter = Math.floor(Math.random() * (exp * 0.2));\n return Math.min(maxMs, exp + jitter);\n }\n\n /**\n * Abstract method for message processing logic.\n */\n protected async processMessage(message: QueueMessage<T>, rawMessage, channel): Promise<void> {\n await this.updateStatusInDatabase('started', message);\n\n // Capture the results of handling the task.\n const result = await this.subscribe(message);\n\n // Ack the message. \n channel.ack(rawMessage);\n\n // Persist success output and timing.\n await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');\n\n }\n\n private async updateStatusInDatabase(stage: string, message: QueueMessage<T>, error: string = '', result: string = '') {\n\n // Update the existing message record by messageId; creation happens upstream.\n try {\n // 1. resolve the queue first\n const mqMessage = await this.mqMessageService.repo.findOne({\n where: {\n messageId: message.messageId,\n }\n });\n\n if (mqMessage) {\n const updatedFields = {\n stage: stage\n };\n if (stage === 'failed' || stage === 'succeeded') {\n updatedFields['finishedAt'] = new Date();\n updatedFields['elapsedMillis'] = updatedFields['finishedAt'].getTime() - mqMessage.startedAt.getTime();\n }\n if (stage === 'succeeded') {\n updatedFields['output'] = result;\n }\n if (stage === 'failed') {\n updatedFields['error'] = error;\n }\n await this.mqMessageService.repo.update(mqMessage.id, updatedFields);\n }\n }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n\n }\n\n}\n"]}
|
|
1
|
+
{"version":3,"file":"rabbitmq-subscriber.service.js","sourceRoot":"","sources":["../../../src/services/queues/rabbitmq-subscriber.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger, OnModuleInit } from '@nestjs/common';\nimport * as amqp from 'amqplib';\nimport { QueuesModuleOptions } from \"../../interfaces\";\nimport { QueueMessage, QueueSubscriber } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\nimport { buildNamespacedQueueName } from './common';\n\n\nexport abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscriber<T> { // TODO This can be made a generic type for better type visibility\n private _loggerInstance?: Logger;\n private readonly url: string;\n private readonly serviceRole: string;\n private connection: amqp.Connection | null = null;\n private channel: amqp.Channel | null = null;\n private consumerTag: string | null = null;\n private reconnectPromise: Promise<void> | null = null;\n private reconnectAttempt = 0;\n private stopping = false;\n\n constructor(protected readonly mqMessageService: MqMessageService, protected readonly mqMessageQueueService: MqMessageQueueService) {\n this.url = process.env.QUEUES_RABBIT_MQ_URL;\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.url) {\n this.logger.debug('RabbitMqPublisher url is not defined in the environment variables');\n }\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n // this.logger.debug(`RabbitMqSubscriber instance created with options: ${JSON.stringify(this.options())} and url: ${this.url}`);\n }\n\n protected get loggerContext(): string {\n return this.constructor.name;\n }\n\n protected get logger(): Logger {\n if (!this._loggerInstance) {\n this._loggerInstance = new Logger(this.loggerContext);\n }\n return this._loggerInstance;\n }\n\n abstract subscribe(message: QueueMessage<T>);\n\n abstract options(): QueuesModuleOptions;\n\n async establishConnection(): Promise<amqp.Connection> {\n\n const url = new URL(this.url);\n\n // this.logger.debug(`user: ${url.username}`);\n // // just for local debug, don’t log in prod\n // this.logger.debug(`pass: ${url.password}`);\n // this.logger.debug(`path (vhost): ${url.pathname}`);\n\n const connection = await amqp.connect({\n protocol: url.protocol.replace(':', ''),\n hostname: url.hostname,\n port: parseInt(url.port),\n username: url.username,\n password: decodeURIComponent(url.password),\n frameMax: 131072,\n heartbeat: 30,\n });\n\n return connection\n }\n\n async onModuleInit(): Promise<void> {\n // Not using SettingService here as that will necessitate all implementors of RabbitMqSubscriber to also inject SettingService which is not ideal. \n // Instead we directly read the environment variables here.\n const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'rabbitmq';\n const solidCliRunning = process.env.SOLID_CLI_RUNNING || \"false\";\n const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();\n\n // we will start subscriber only if the current service role is subscriber. \n if (this.url && ['both', 'subscriber'].includes(this.serviceRole) && solidCliRunning === \"false\" && defaultBroker === 'rabbitmq') {\n const options = this.options();\n const queueName = options.queueName;\n\n if (queueNameRegex && queueNameRegex !== \"all\") {\n try {\n const regex = new RegExp(queueNameRegex);\n if (!regex.test(queueName)) {\n this.logger.log(`RabbitMqSubscriber for queue ${queueName} is disabled because it does not match QUEUES_QUEUE_NAME_REGEX_TO_ENABLE=${queueNameRegex}`);\n return;\n }\n } catch (error) {\n this.logger.error(`Invalid QUEUES_QUEUE_NAME_REGEX_TO_ENABLE regex \"${queueNameRegex}\". Subscriber for queue ${queueName} will not start.`);\n return;\n }\n }\n\n const namespacedQueueName = buildNamespacedQueueName(queueName);\n try {\n await this.connectAndConsume(namespacedQueueName);\n } catch (err) {\n this.logger.error(`Failed to connect to RabbitMQ for queue ${namespacedQueueName}: ${(err as Error).message}`, (err as Error).stack);\n this.triggerReconnect(namespacedQueueName, 'initial connection failure');\n }\n\n this.logger.log(`RabbitMqSubscriber ready to consume messages: ${JSON.stringify(options)} and url: ${this.url}`);\n }\n }\n\n private async connectAndConsume(queueName: string): Promise<void> {\n await this.cleanup();\n this.logger.log(`RabbitMqSubscriber in connectAndConsume for queue: ${queueName} and url: ${this.url}`);\n\n const options = this.options();\n const prefetch = options.prefetch ?? 1;\n if (prefetch < 1) {\n throw new Error(`RabbitMqSubscriber prefetch must be >= 1 for queue ${queueName}`);\n }\n\n let connection: amqp.Connection;\n try {\n connection = await this.establishConnection();\n } catch (err) {\n this.logger.error(`Failed to connect to RabbitMQ for queue ${queueName}: ${(err as Error).message}`, (err as Error).stack);\n throw err;\n }\n\n this.connection = connection;\n\n connection.on('error', (err) => {\n if (connection !== this.connection) return;\n this.logger.error(`RabbitMqSubscriber connection error for queue ${queueName}: ${(err as Error).message}`);\n });\n\n connection.on('close', () => {\n if (connection !== this.connection) return;\n this.logger.warn(`RabbitMqSubscriber connection closed for queue ${queueName}`);\n this.triggerReconnect(queueName, 'connection closed');\n });\n\n const channel = await connection.createChannel();\n this.channel = channel;\n\n channel.on('error', (err) => {\n if (channel !== this.channel) return;\n this.logger.error(`RabbitMqSubscriber channel error for queue ${queueName}: ${(err as Error).message}`);\n });\n\n channel.on('close', () => {\n if (channel !== this.channel) return;\n this.logger.warn(`RabbitMqSubscriber channel closed for queue ${queueName}`);\n this.triggerReconnect(queueName, 'channel closed');\n });\n\n // Process one message at a time per consumer to avoid parallel work on the same subscriber instance.\n await channel.prefetch(prefetch);\n\n // Use a direct exchange with a stable routing key so retry DLX can route back to the main queue.\n const exchangeName = `${queueName}.exchange`;\n const routingKey = `${queueName}.routing-key`;\n const retryQueue = `${queueName}.retry`;\n const failedQueue = `${queueName}.failed`;\n\n await channel.assertExchange(exchangeName, 'direct', {});\n await channel.assertQueue(queueName, {});\n await channel.bindQueue(queueName, exchangeName, routingKey);\n\n // Retry queue uses DLX to route expired messages back to the main exchange/routing key.\n await channel.assertQueue(retryQueue, {\n arguments: {\n 'x-dead-letter-exchange': exchangeName,\n 'x-dead-letter-routing-key': routingKey,\n }\n });\n\n await channel.assertQueue(failedQueue, {});\n\n const consumeResult = await channel.consume(\n queueName,\n async (rawMessage) => {\n if (!rawMessage) {\n return;\n }\n\n let message: QueueMessage<T> = null;\n\n try {\n const messageContentString = rawMessage.content.toString();\n message = JSON.parse(messageContentString) as QueueMessage<T>;\n this.logger.debug(`rabbitmq subscriber received message with id: ${message.messageId} for queue ${queueName}`);\n } catch (error) {\n this.logger.error(`Invalid JSON message on queue ${queueName}: ${(error as Error).message}`);\n await this.publishToFailedQueue(queueName, rawMessage.content, channel, error);\n channel.ack(rawMessage);\n return;\n }\n\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n if (!message.currentRetry) message.currentRetry = 0;\n\n try {\n await this.processMessage(message, rawMessage, channel);\n } catch (error) {\n await this.handleProcessingError(message, rawMessage, channel, error, queueName);\n }\n },\n // Explicit ack enables reliable processing and retry routing.\n { noAck: false },\n );\n\n this.consumerTag = consumeResult.consumerTag;\n }\n\n // Retry flow: update DB -> increment retry -> send to retry queue with per-message expiration -> ack original.\n private async handleProcessingError(message: QueueMessage<T>, rawMessage: amqp.ConsumeMessage, channel: amqp.Channel, error: any, queueName: string): Promise<void> {\n const errorMessage = (error as Error)?.message || String(error);\n this.logger.error(`Error processing message on queue ${queueName}: ${errorMessage}`);\n\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n const retryQueue = `${queueName}.retry`;\n const payload = Buffer.from(JSON.stringify(message));\n\n // Per-message expiration keeps the message in the retry queue until TTL, then DLX routes it back.\n channel.sendToQueue(retryQueue, payload, {\n expiration: String(message.retryInterval || 1000),\n headers: {\n 'x-error': errorMessage,\n }\n });\n\n channel.ack(rawMessage);\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms on queue ${queueName}`);\n return;\n }\n\n await this.updateStatusInDatabase('failed', message, errorMessage, '');\n channel.ack(rawMessage);\n await this.publishToFailedQueue(queueName, Buffer.from(JSON.stringify(message)), channel, error);\n this.logger.error(`Message failed after ${message.retryCount} attempts on queue ${queueName}: ${errorMessage}`);\n }\n\n private async publishToFailedQueue(queueName: string, payload: Buffer | string, channel: amqp.Channel, error?: any): Promise<void> {\n const failedQueue = `${queueName}.failed`;\n const body = Buffer.isBuffer(payload) ? payload : Buffer.from(payload);\n const errorMessage = (error as Error)?.message || String(error || '');\n\n try {\n channel.sendToQueue(failedQueue, body, errorMessage ? {\n headers: { 'x-error': errorMessage }\n } : undefined);\n } catch (err) {\n this.logger.error(`Failed to publish to failed queue ${failedQueue}: ${(err as Error).message}`);\n }\n }\n\n private triggerReconnect(queueName: string, reason: string) {\n if (this.stopping) return;\n if (this.reconnectPromise) return;\n\n this.reconnectPromise = this.reconnectLoop(queueName, reason)\n .finally(() => {\n this.reconnectPromise = null;\n });\n }\n\n // Reconnect with backoff to avoid hammering the broker during outages.\n private async reconnectLoop(queueName: string, reason: string): Promise<void> {\n this.logger.warn(`RabbitMqSubscriber reconnecting for queue ${queueName}: ${reason}`);\n\n while (!this.stopping) {\n try {\n await this.connectAndConsume(queueName);\n this.reconnectAttempt = 0;\n this.logger.log(`RabbitMqSubscriber reconnected for queue ${queueName}`);\n return;\n } catch (err) {\n this.reconnectAttempt += 1;\n const delay = this.backoff();\n this.logger.warn(`RabbitMqSubscriber reconnect failed for queue ${queueName}; retrying in ${delay}ms`);\n await this.sleep(delay);\n }\n }\n }\n\n private async cleanup(): Promise<void> {\n const channel = this.channel;\n const connection = this.connection;\n const consumerTag = this.consumerTag;\n\n this.channel = null;\n this.connection = null;\n this.consumerTag = null;\n\n if (channel) {\n try {\n if (consumerTag) {\n await channel.cancel(consumerTag);\n }\n } catch (_) {\n // ignore\n }\n\n try {\n await channel.close();\n } catch (_) {\n // ignore\n }\n }\n\n if (connection) {\n try {\n await connection.close();\n } catch (_) {\n // ignore\n }\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n // Exponential backoff with jitter, capped to 30s.\n private backoff(): number {\n const baseMs = 1000;\n const maxMs = 30_000;\n const exp = Math.min(maxMs, baseMs * Math.pow(2, this.reconnectAttempt));\n const jitter = Math.floor(Math.random() * (exp * 0.2));\n return Math.min(maxMs, exp + jitter);\n }\n\n /**\n * Abstract method for message processing logic.\n */\n protected async processMessage(message: QueueMessage<T>, rawMessage, channel): Promise<void> {\n await this.updateStatusInDatabase('started', message);\n\n // Capture the results of handling the task.\n const result = await this.subscribe(message);\n\n // Ack the message. \n channel.ack(rawMessage);\n\n // Persist success output and timing.\n await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');\n\n }\n\n private async updateStatusInDatabase(stage: string, message: QueueMessage<T>, error: string = '', result: string = '') {\n\n // Update the existing message record by messageId; creation happens upstream.\n try {\n // 1. resolve the queue first\n const mqMessage = await this.mqMessageService.repo.findOne({\n where: {\n messageId: message.messageId,\n }\n });\n\n if (mqMessage) {\n const updatedFields = {\n stage: stage\n };\n if (stage === 'failed' || stage === 'succeeded') {\n updatedFields['finishedAt'] = new Date();\n updatedFields['elapsedMillis'] = updatedFields['finishedAt'].getTime() - mqMessage.startedAt.getTime();\n }\n if (stage === 'succeeded') {\n updatedFields['output'] = result;\n }\n if (stage === 'failed') {\n updatedFields['error'] = error;\n }\n await this.mqMessageService.repo.update(mqMessage.id, updatedFields);\n }\n }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n\n }\n\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidxai/core",
|
|
3
|
-
"version": "0.1.6-beta.
|
|
3
|
+
"version": "0.1.6-beta.6",
|
|
4
4
|
"description": "This module is a NestJS module containing all the required core providers required by a Solid application",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -5721,7 +5721,7 @@
|
|
|
5721
5721
|
"modelUserKey": "listOfValues"
|
|
5722
5722
|
},
|
|
5723
5723
|
{
|
|
5724
|
-
"displayName": "Import Transactions
|
|
5724
|
+
"displayName": "Import Transactions",
|
|
5725
5725
|
"name": "importTransaction-list-action",
|
|
5726
5726
|
"type": "solid",
|
|
5727
5727
|
"domain": "",
|
|
@@ -5734,7 +5734,7 @@
|
|
|
5734
5734
|
"modelUserKey": "importTransaction"
|
|
5735
5735
|
},
|
|
5736
5736
|
{
|
|
5737
|
-
"displayName": "User Activity History
|
|
5737
|
+
"displayName": "User Activity History",
|
|
5738
5738
|
"name": "userActivityHistory-list-action",
|
|
5739
5739
|
"type": "solid",
|
|
5740
5740
|
"domain": "",
|
|
@@ -5746,6 +5746,19 @@
|
|
|
5746
5746
|
"moduleUserKey": "solid-core",
|
|
5747
5747
|
"modelUserKey": "userActivityHistory"
|
|
5748
5748
|
},
|
|
5749
|
+
{
|
|
5750
|
+
"displayName": "User Activity History",
|
|
5751
|
+
"name": "userActivityHistory-tree-action",
|
|
5752
|
+
"type": "solid",
|
|
5753
|
+
"domain": "",
|
|
5754
|
+
"context": "",
|
|
5755
|
+
"customComponent": "",
|
|
5756
|
+
"customIsModal": true,
|
|
5757
|
+
"serverEndpoint": "",
|
|
5758
|
+
"viewUserKey": "userActivityHistory-tree-view",
|
|
5759
|
+
"moduleUserKey": "solid-core",
|
|
5760
|
+
"modelUserKey": "userActivityHistory"
|
|
5761
|
+
},
|
|
5749
5762
|
{
|
|
5750
5763
|
"displayName": "App Settings",
|
|
5751
5764
|
"name": "appSettings-action",
|
|
@@ -11157,7 +11170,64 @@
|
|
|
11157
11170
|
{
|
|
11158
11171
|
"type": "field",
|
|
11159
11172
|
"attrs": {
|
|
11160
|
-
"name": "
|
|
11173
|
+
"name": "createdAt",
|
|
11174
|
+
"sortable": true,
|
|
11175
|
+
"filterable": true
|
|
11176
|
+
}
|
|
11177
|
+
}
|
|
11178
|
+
]
|
|
11179
|
+
}
|
|
11180
|
+
},
|
|
11181
|
+
{
|
|
11182
|
+
"name": "userActivityHistory-tree-view",
|
|
11183
|
+
"displayName": "User Activity History",
|
|
11184
|
+
"type": "tree",
|
|
11185
|
+
"context": "{}",
|
|
11186
|
+
"moduleUserKey": "solid-core",
|
|
11187
|
+
"modelUserKey": "userActivityHistory",
|
|
11188
|
+
"layout": {
|
|
11189
|
+
"type": "tree",
|
|
11190
|
+
"attrs": {
|
|
11191
|
+
"pagination": true,
|
|
11192
|
+
"pageSizeOptions": [
|
|
11193
|
+
10,
|
|
11194
|
+
25,
|
|
11195
|
+
50
|
|
11196
|
+
],
|
|
11197
|
+
"enableGlobalSearch": true,
|
|
11198
|
+
"create": true,
|
|
11199
|
+
"edit": true,
|
|
11200
|
+
"delete": true
|
|
11201
|
+
},
|
|
11202
|
+
"children": [
|
|
11203
|
+
{
|
|
11204
|
+
"type": "field",
|
|
11205
|
+
"attrs": {
|
|
11206
|
+
"name": "id",
|
|
11207
|
+
"sortable": true,
|
|
11208
|
+
"filterable": true
|
|
11209
|
+
}
|
|
11210
|
+
},
|
|
11211
|
+
{
|
|
11212
|
+
"type": "field",
|
|
11213
|
+
"attrs": {
|
|
11214
|
+
"name": "user",
|
|
11215
|
+
"sortable": true,
|
|
11216
|
+
"filterable": true
|
|
11217
|
+
}
|
|
11218
|
+
},
|
|
11219
|
+
{
|
|
11220
|
+
"type": "field",
|
|
11221
|
+
"attrs": {
|
|
11222
|
+
"name": "event",
|
|
11223
|
+
"sortable": true,
|
|
11224
|
+
"filterable": true
|
|
11225
|
+
}
|
|
11226
|
+
},
|
|
11227
|
+
{
|
|
11228
|
+
"type": "field",
|
|
11229
|
+
"attrs": {
|
|
11230
|
+
"name": "ipAddress",
|
|
11161
11231
|
"sortable": true,
|
|
11162
11232
|
"filterable": true
|
|
11163
11233
|
}
|
|
@@ -464,10 +464,6 @@ export class AuthenticationService {
|
|
|
464
464
|
|
|
465
465
|
private async notifyUserOnOtpInitiateRegistration(user: User, registrationValidationSource: string) {
|
|
466
466
|
const companyLogo = await this.getCompanyLogo();
|
|
467
|
-
const dummyOtp = this.getDummyOtpForUser(user);
|
|
468
|
-
|
|
469
|
-
if (dummyOtp)
|
|
470
|
-
return; // Do nothing if dummy otp is configured.
|
|
471
467
|
if (registrationValidationSource === PasswordlessLoginValidateWhatSources.EMAIL) {
|
|
472
468
|
const mailService = this.mailServiceFactory.getMailService();
|
|
473
469
|
mailService.sendEmailUsingTemplate(
|
|
@@ -594,13 +590,12 @@ export class AuthenticationService {
|
|
|
594
590
|
return true;
|
|
595
591
|
}
|
|
596
592
|
|
|
597
|
-
private async otp(
|
|
593
|
+
private async otp(): Promise<otp> {
|
|
598
594
|
const now = new Date();
|
|
599
595
|
const otpExpiry = this.settingService.getConfigValue<SolidCoreSetting>('otpExpiry');
|
|
600
|
-
const dummyOtp = this.getDummyOtpForUser(user);
|
|
601
596
|
now.setMinutes(now.getMinutes() + otpExpiry);
|
|
602
597
|
return {
|
|
603
|
-
token:
|
|
598
|
+
token: randomInt(100000, 999999).toString(),
|
|
604
599
|
expiresAt: now,
|
|
605
600
|
};
|
|
606
601
|
}
|
|
@@ -692,8 +687,11 @@ export class AuthenticationService {
|
|
|
692
687
|
|
|
693
688
|
const type = this.resolveLoginType(signInDto);
|
|
694
689
|
const user = await this.findUserForLogin(type, signInDto.identifier);
|
|
695
|
-
|
|
696
|
-
|
|
690
|
+
const dummyOtp = this.getDummyOtpForUser(user);
|
|
691
|
+
if (!dummyOtp) {
|
|
692
|
+
await this.assignLoginOtp(user, type);
|
|
693
|
+
this.notifyUserOnOtpInititateLogin(user, type);
|
|
694
|
+
}
|
|
697
695
|
return this.buildLoginOtpResponse(user, type);
|
|
698
696
|
}
|
|
699
697
|
|
|
@@ -738,15 +736,22 @@ export class AuthenticationService {
|
|
|
738
736
|
}
|
|
739
737
|
|
|
740
738
|
private async assignLoginOtp(user: User, type: PasswordlessLoginValidateWhatSources): Promise<void> {
|
|
741
|
-
const { token, expiresAt } = await this.otp(
|
|
739
|
+
const { token, expiresAt } = await this.otp();
|
|
742
740
|
if (type === PasswordlessLoginValidateWhatSources.EMAIL) {
|
|
743
741
|
user.emailVerificationTokenOnLogin = token;
|
|
744
742
|
user.emailVerificationTokenOnLoginExpiresAt = expiresAt;
|
|
743
|
+
await this.userRepository.update(user.id, {
|
|
744
|
+
emailVerificationTokenOnLogin: token,
|
|
745
|
+
emailVerificationTokenOnLoginExpiresAt: expiresAt,
|
|
746
|
+
});
|
|
745
747
|
} else {
|
|
746
748
|
user.mobileVerificationTokenOnLogin = token;
|
|
747
749
|
user.mobileVerificationTokenOnLoginExpiresAt = expiresAt;
|
|
750
|
+
await this.userRepository.update(user.id, {
|
|
751
|
+
mobileVerificationTokenOnLogin: token,
|
|
752
|
+
mobileVerificationTokenOnLoginExpiresAt: expiresAt,
|
|
753
|
+
});
|
|
748
754
|
}
|
|
749
|
-
await this.userRepository.save(user);
|
|
750
755
|
}
|
|
751
756
|
|
|
752
757
|
private buildLoginOtpResponse(user: User, type: PasswordlessLoginValidateWhatSources) {
|
|
@@ -815,6 +820,15 @@ export class AuthenticationService {
|
|
|
815
820
|
|
|
816
821
|
const user = await this.findUserForLogin(type, identifier, { withRoles: true });
|
|
817
822
|
this.checkAccountBlocked(user);
|
|
823
|
+
const dummyOtp = this.getDummyOtpForUser(user);
|
|
824
|
+
|
|
825
|
+
if (dummyOtp) {
|
|
826
|
+
if (otp !== dummyOtp) {
|
|
827
|
+
throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);
|
|
828
|
+
}
|
|
829
|
+
return this.buildLoginTokenResponse(user);
|
|
830
|
+
}
|
|
831
|
+
|
|
818
832
|
try {
|
|
819
833
|
this.validateLoginOtp(user, otp, type);
|
|
820
834
|
} catch (e) {
|
|
@@ -822,14 +836,9 @@ export class AuthenticationService {
|
|
|
822
836
|
throw e;
|
|
823
837
|
}
|
|
824
838
|
|
|
825
|
-
|
|
826
|
-
const dummyOtp = this.getDummyOtpForUser(user);
|
|
827
|
-
if (!dummyOtp)
|
|
828
|
-
this.clearLoginOtp(user, type);
|
|
829
|
-
|
|
830
|
-
user.failedLoginAttempts = 0;
|
|
839
|
+
await this.clearLoginOtp(user, type);
|
|
831
840
|
await this.userActivityHistoryService.logEvent('login', user);
|
|
832
|
-
await this.
|
|
841
|
+
await this.resetFailedAttempts(user);
|
|
833
842
|
return this.buildLoginTokenResponse(user);
|
|
834
843
|
}
|
|
835
844
|
|
|
@@ -846,15 +855,27 @@ export class AuthenticationService {
|
|
|
846
855
|
}
|
|
847
856
|
}
|
|
848
857
|
|
|
849
|
-
private clearLoginOtp(user: User, type: PasswordlessLoginValidateWhatSources): void {
|
|
858
|
+
private async clearLoginOtp(user: User, type: PasswordlessLoginValidateWhatSources): Promise<void> {
|
|
850
859
|
if (type === PasswordlessLoginValidateWhatSources.EMAIL) {
|
|
851
|
-
|
|
860
|
+
const verifiedAt = new Date();
|
|
861
|
+
user.emailVerifiedOnLoginAt = verifiedAt;
|
|
852
862
|
user.emailVerificationTokenOnLogin = null;
|
|
853
863
|
user.emailVerificationTokenOnLoginExpiresAt = null;
|
|
864
|
+
await this.userRepository.update(user.id, {
|
|
865
|
+
emailVerifiedOnLoginAt: verifiedAt,
|
|
866
|
+
emailVerificationTokenOnLogin: null,
|
|
867
|
+
emailVerificationTokenOnLoginExpiresAt: null,
|
|
868
|
+
});
|
|
854
869
|
} else {
|
|
855
|
-
|
|
870
|
+
const verifiedAt = new Date();
|
|
871
|
+
user.mobileVerifiedOnLoginAt = verifiedAt;
|
|
856
872
|
user.mobileVerificationTokenOnLogin = null;
|
|
857
873
|
user.mobileVerificationTokenOnLoginExpiresAt = null;
|
|
874
|
+
await this.userRepository.update(user.id, {
|
|
875
|
+
mobileVerifiedOnLoginAt: verifiedAt,
|
|
876
|
+
mobileVerificationTokenOnLogin: null,
|
|
877
|
+
mobileVerificationTokenOnLoginExpiresAt: null,
|
|
878
|
+
});
|
|
858
879
|
}
|
|
859
880
|
}
|
|
860
881
|
|
|
@@ -1297,14 +1318,15 @@ export class AuthenticationService {
|
|
|
1297
1318
|
}
|
|
1298
1319
|
|
|
1299
1320
|
private async incrementFailedAttempts(user: User): Promise<void> {
|
|
1300
|
-
user.failedLoginAttempts
|
|
1301
|
-
|
|
1321
|
+
const nextFailedAttempts = (user.failedLoginAttempts ?? 0) + 1;
|
|
1322
|
+
user.failedLoginAttempts = nextFailedAttempts;
|
|
1323
|
+
await this.userRepository.update(user.id, { failedLoginAttempts: nextFailedAttempts });
|
|
1302
1324
|
}
|
|
1303
1325
|
|
|
1304
1326
|
private async resetFailedAttempts(user: User): Promise<void> {
|
|
1305
1327
|
if (user.failedLoginAttempts === 0) return;
|
|
1306
1328
|
user.failedLoginAttempts = 0;
|
|
1307
|
-
await this.userRepository.
|
|
1329
|
+
await this.userRepository.update(user.id, { failedLoginAttempts: 0 });
|
|
1308
1330
|
}
|
|
1309
1331
|
|
|
1310
1332
|
//FIXME - Pending implementation
|
|
@@ -7,7 +7,7 @@ import { PollerService } from '../poller.service';
|
|
|
7
7
|
import { buildNamespacedQueueName } from './common';
|
|
8
8
|
|
|
9
9
|
export abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscriber<T> {
|
|
10
|
-
private
|
|
10
|
+
private _loggerInstance?: Logger;
|
|
11
11
|
private readonly url: string;
|
|
12
12
|
private readonly serviceRole: string;
|
|
13
13
|
|
|
@@ -23,6 +23,17 @@ export abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscr
|
|
|
23
23
|
// this.logger.debug(`DatabaseSubscriber instance created with options: ${JSON.stringify(this.options())}`);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
protected get loggerContext(): string {
|
|
27
|
+
return this.constructor.name;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
protected get logger(): Logger {
|
|
31
|
+
if (!this._loggerInstance) {
|
|
32
|
+
this._loggerInstance = new Logger(this.loggerContext);
|
|
33
|
+
}
|
|
34
|
+
return this._loggerInstance;
|
|
35
|
+
}
|
|
36
|
+
|
|
26
37
|
abstract subscribe(message: QueueMessage<T>);
|
|
27
38
|
|
|
28
39
|
abstract options(): QueuesModuleOptions;
|
|
@@ -23,14 +23,16 @@ export class PublisherFactory<T> {
|
|
|
23
23
|
// Register all ISolidDatabaseModules implementations
|
|
24
24
|
let actualPublisherToUse = this.solidIntrospectionService.getProvider(resolvedPublisherName);
|
|
25
25
|
if (!actualPublisherToUse) {
|
|
26
|
+
// Relaxed extra check in place to make sure we do not have to refactor old publishers or publishers named without the ____RabbitMq or ____Database convention
|
|
27
|
+
actualPublisherToUse = this.solidIntrospectionService.getProvider(publisherName);
|
|
26
28
|
|
|
27
29
|
// Extra check in place to make sure we do not have to refactor old publishers which have been created earlier.
|
|
28
|
-
if (defaultBrokerToUse === 'rabbitmq') {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
30
|
+
// if (defaultBrokerToUse === 'rabbitmq') {
|
|
31
|
+
// actualPublisherToUse = this.solidIntrospectionService.getProvider(publisherName);
|
|
32
|
+
// }
|
|
33
|
+
}
|
|
34
|
+
if (!actualPublisherToUse) {
|
|
35
|
+
throw new Error(`Unable to locate publisher with name ${resolvedPublisherName}`);
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
// type safe
|