UNPKG

@piggly/fastify-chassis

Version:

An ESM/CommonJS toolkit to help you to do common operations in your back-end applications with Fastify and NodeJS.

135 lines 4.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NonceTokenService = void 0; const tslib_1 = require("tslib"); const node_crypto_1 = tslib_1.__importDefault(require("node:crypto")); const ddd_toolkit_1 = require("@piggly/ddd-toolkit"); /** * @file Nonce service. * @copyright Piggly Lab 2025 * @since 7.0.0 * @author Caique Araujo <caique@piggly.com.br> */ class NonceTokenService { /** * Repository. * * @type {IStoreService} * @protected * @memberof NonceTokenService * @since 7.0.0 * @author Caique Araujo <caique@piggly.com.br> */ _repository; /** * Constructor. * * @param {IStoreService} repository * @public * @constructor * @memberof NonceTokenService * @since 7.0.0 * @author Caique Araujo <caique@piggly.com.br> */ constructor(repository) { this._repository = repository; } /** * Issue one or more nonces. * * @param {number} size * @returns {Promise<Array<string>>} * @throws {Error} If failed to issue nonce. Error may be produced by store service. * @since 7.0.0 * @author Caique Araujo <caique@piggly.com.br> */ async issue(size = 1, ttl = 3600) { const nonces = []; for (let i = 0; i < size; i++) { const nonce = NonceTokenService.generateClientSecret(32); const response = await this._repository.set(`nonce:${nonce}`, '1', ttl); if (response === false) { throw new Error('Failed to issue nonce'); } nonces.push(nonce); } return nonces; } /** * Verify a nonce. * * If will return undefined if nonce is not found * or the same nonce if found. But, if regenerate * is true, it will regenerate the nonce and return * the new nonce. * * @param {string} nonce * @param {boolean} regenerate * @param {number} ttl * @returns {Promise<TOrUndefined<string>>} * @throws {Error} If failed to verify/regenerate nonce. Error may be produced by store service. * @since 7.0.0 * @author Caique Araujo <caique@piggly.com.br> */ async verify(nonce, regenerate, ttl) { const response = await this._repository.getAndDelete(`nonce:${nonce}`); if (!response) { return undefined; } if (regenerate === false) { return nonce; } const nonces = await this.issue(1, ttl); return nonces[0]; } /** * Random generates a client secret. * * @param {number} [size=36] * @public * @static * @memberof NonceTokenService * @since 7.6.0 * @author Caique Araujo <caique@piggly.com.br> */ static generateClientSecret(size = 36) { const buffer = node_crypto_1.default.randomBytes(size); return buffer .toString('base64') .replace(/\//g, '_') .replace(/\+/g, '-') .replace(/=/g, ''); } /** * Register application service. * * @param {NonceTokenService} store * @public * @static * @memberof NonceTokenService * @since 7.0.0 * @author Caique Araujo <caique@piggly.com.br> */ static register(store) { if (ddd_toolkit_1.ServiceProvider.has('NonceTokenService')) { return; } ddd_toolkit_1.ServiceProvider.register('NonceTokenService', new NonceTokenService(store)); } /** * Resolve application service. * * @returns {NonceTokenService} * @throws {Error} If service is not registered. * @public * @static * @memberof NonceTokenService * @since 7.0.0 * @author Caique Araujo <caique@piggly.com.br> */ static resolve() { return ddd_toolkit_1.ServiceProvider.resolve('NonceTokenService'); } } exports.NonceTokenService = NonceTokenService; //# sourceMappingURL=NonceTokenService.js.map