@nestlab/google-recaptcha
Version:
Google recaptcha module for NestJS.
120 lines (119 loc) • 5.99 kB
JavaScript
;
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;