@nestlab/google-recaptcha
Version:
Google recaptcha module for NestJS.
123 lines (122 loc) • 6.77 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.GoogleRecaptchaEnterpriseValidator = void 0;
const common_1 = require("@nestjs/common");
const provider_declarations_1 = require("../../provider.declarations");
const abstract_google_recaptcha_validator_1 = require("./abstract-google-recaptcha-validator");
const recaptcha_verification_result_1 = require("../../models/recaptcha-verification-result");
const error_code_1 = require("../../enums/error-code");
const google_recaptcha_network_exception_1 = require("../../exceptions/google-recaptcha-network.exception");
const google_recaptcha_context_1 = require("../../enums/google-recaptcha-context");
const enterprise_reason_transformer_1 = require("../enterprise-reason.transformer");
const get_error_info_1 = require("../../helpers/get-error-info");
const recaptcha_config_ref_1 = require("../../models/recaptcha-config-ref");
let GoogleRecaptchaEnterpriseValidator = class GoogleRecaptchaEnterpriseValidator extends abstract_google_recaptcha_validator_1.AbstractGoogleRecaptchaValidator {
constructor(axios, logger, configRef, enterpriseReasonTransformer) {
super(configRef);
this.axios = axios;
this.logger = logger;
this.enterpriseReasonTransformer = enterpriseReasonTransformer;
this.headers = { 'Content-Type': 'application/json' };
}
async validate(options) {
var _a, _b, _c, _d;
const [result, errorDetails] = await this.verifyResponse(options.response, options.action, options.remoteIp);
const errors = [];
let success = ((_a = result === null || result === void 0 ? void 0 : result.tokenProperties) === null || _a === void 0 ? void 0 : _a.valid) || false;
if (!errorDetails) {
if (result.tokenProperties) {
if (result.tokenProperties.invalidReason) {
const invalidReasonCode = this.enterpriseReasonTransformer.transform(result.tokenProperties.invalidReason);
if (invalidReasonCode) {
errors.push(invalidReasonCode);
}
}
if (success && !this.isValidAction(result.tokenProperties.action, options)) {
success = false;
errors.push(error_code_1.ErrorCode.ForbiddenAction);
}
}
if (result.riskAnalysis && !this.isValidScore(result.riskAnalysis.score, options.score)) {
success = false;
errors.push(error_code_1.ErrorCode.LowScore);
}
}
if (!success && !errors.length) {
errorDetails ? errors.push(error_code_1.ErrorCode.UnknownError) : errors.push(error_code_1.ErrorCode.InvalidInputResponse);
}
return new recaptcha_verification_result_1.RecaptchaVerificationResult({
success,
errors,
nativeResponse: result,
remoteIp: options.remoteIp,
score: (_b = result === null || result === void 0 ? void 0 : result.riskAnalysis) === null || _b === void 0 ? void 0 : _b.score,
action: (_c = result === null || result === void 0 ? void 0 : result.tokenProperties) === null || _c === void 0 ? void 0 : _c.action,
hostname: ((_d = result === null || result === void 0 ? void 0 : result.tokenProperties) === null || _d === void 0 ? void 0 : _d.hostname) || '',
});
}
verifyResponse(response, expectedAction, remoteIp) {
const projectId = this.options.valueOf.enterprise.projectId;
const body = {
event: {
expectedAction,
siteKey: this.options.valueOf.enterprise.siteKey,
token: response,
userIpAddress: remoteIp,
},
};
const url = `https://recaptchaenterprise.googleapis.com/v1/projects/${projectId}/assessments`;
const config = {
headers: this.headers,
params: {
key: this.options.valueOf.enterprise.apiKey,
},
};
if (this.options.valueOf.debug) {
this.logger.debug({ body }, `${google_recaptcha_context_1.GoogleRecaptchaContext.GoogleRecaptchaEnterprise}.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.GoogleRecaptchaEnterprise}.response`);
}
return [data, null];
})
.catch((err) => {
if (this.options.valueOf.debug) {
this.logger.debug((0, get_error_info_1.getErrorInfo)(err), `${google_recaptcha_context_1.GoogleRecaptchaContext.GoogleRecaptchaEnterprise}.error`);
}
const networkErrorCode = err.isAxiosError && !err.response && err.code;
if (networkErrorCode) {
throw new google_recaptcha_network_exception_1.GoogleRecaptchaNetworkException(networkErrorCode);
}
const errData = {
status: err.response.status,
data: err.response.data,
};
return [null, errData];
});
}
};
GoogleRecaptchaEnterpriseValidator = __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,
enterprise_reason_transformer_1.EnterpriseReasonTransformer])
], GoogleRecaptchaEnterpriseValidator);
exports.GoogleRecaptchaEnterpriseValidator = GoogleRecaptchaEnterpriseValidator;