UNPKG

@nestlab/google-recaptcha

Version:
120 lines (119 loc) 5.99 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GoogleRecaptchaValidator = void 0; const common_1 = require("@nestjs/common"); const provider_declarations_1 = require("../../provider.declarations"); const qs = require("querystring"); const google_recaptcha_network_1 = require("../../enums/google-recaptcha-network"); const error_code_1 = require("../../enums/error-code"); const google_recaptcha_network_exception_1 = require("../../exceptions/google-recaptcha-network.exception"); const abstract_google_recaptcha_validator_1 = require("./abstract-google-recaptcha-validator"); const recaptcha_verification_result_1 = require("../../models/recaptcha-verification-result"); const google_recaptcha_context_1 = require("../../enums/google-recaptcha-context"); const get_error_info_1 = require("../../helpers/get-error-info"); const recaptcha_config_ref_1 = require("../../models/recaptcha-config-ref"); let GoogleRecaptchaValidator = class GoogleRecaptchaValidator extends abstract_google_recaptcha_validator_1.AbstractGoogleRecaptchaValidator { constructor(axios, logger, configRef) { super(configRef); this.axios = axios; this.logger = logger; this.defaultNetwork = google_recaptcha_network_1.GoogleRecaptchaNetwork.Google; this.headers = { 'Content-Type': 'application/x-www-form-urlencoded' }; } /** * @throws GoogleRecaptchaNetworkException * @param {VerifyResponseOptions} options */ async validate(options) { const result = await this.verifyResponse(options.response, options.remoteIp); if (!this.isUseV3(result)) { const resV2 = result; return new recaptcha_verification_result_1.RecaptchaVerificationResult({ nativeResponse: resV2, remoteIp: options.remoteIp, score: undefined, action: undefined, errors: resV2.errors, success: resV2.success, hostname: resV2.hostname, }); } if (!this.isValidAction(result.action, options)) { result.success = false; result.errors.push(error_code_1.ErrorCode.ForbiddenAction); } if (!this.isValidScore(result.score, options.score)) { result.success = false; result.errors.push(error_code_1.ErrorCode.LowScore); } const nativeResponse = Object.assign({}, result); return new recaptcha_verification_result_1.RecaptchaVerificationResult({ nativeResponse: nativeResponse, remoteIp: options.remoteIp, score: result.score, errors: result.errors, success: result.success, action: result.action, hostname: result.hostname, }); } verifyResponse(response, remoteIp) { const body = qs.stringify({ secret: this.options.valueOf.secretKey, response, remoteip: remoteIp }); const url = this.options.valueOf.network || this.defaultNetwork; const config = { headers: this.headers, }; if (this.options.valueOf.debug) { this.logger.debug({ body }, `${google_recaptcha_context_1.GoogleRecaptchaContext.GoogleRecaptcha}.request`); } return this.axios.post(url, body, config) .then((res) => res.data) .then((data) => { if (this.options.valueOf.debug) { this.logger.debug(data, `${google_recaptcha_context_1.GoogleRecaptchaContext.GoogleRecaptcha}.response`); } return data; }) .then((result) => (Object.assign(Object.assign({}, result), { errors: result['error-codes'] || [] }))) .then((result) => { delete result['error-codes']; return result; }) .catch((err) => { if (this.options.valueOf.debug) { this.logger.debug((0, get_error_info_1.getErrorInfo)(err), `${google_recaptcha_context_1.GoogleRecaptchaContext.GoogleRecaptcha}.error`); } const networkErrorCode = err.isAxiosError && !err.response && err.code; if (networkErrorCode) { throw new google_recaptcha_network_exception_1.GoogleRecaptchaNetworkException(networkErrorCode); } return { success: false, errors: [error_code_1.ErrorCode.UnknownError], }; }); } isUseV3(v) { return 'score' in v && typeof v['score'] === 'number' && 'action' in v && typeof v['action'] === 'string'; } }; GoogleRecaptchaValidator = __decorate([ (0, common_1.Injectable)(), __param(0, (0, common_1.Inject)(provider_declarations_1.RECAPTCHA_AXIOS_INSTANCE)), __param(1, (0, common_1.Inject)(provider_declarations_1.RECAPTCHA_LOGGER)), __metadata("design:paramtypes", [Function, common_1.Logger, recaptcha_config_ref_1.RecaptchaConfigRef]) ], GoogleRecaptchaValidator); exports.GoogleRecaptchaValidator = GoogleRecaptchaValidator;