@nestlab/google-recaptcha
Advanced tools
Comparing version 1.2.1 to 1.2.2
import { RecaptchaResponseProvider } from '../types'; | ||
export declare function Recaptcha(response?: RecaptchaResponseProvider): MethodDecorator; | ||
export declare function Recaptcha(response?: RecaptchaResponseProvider): MethodDecorator & ClassDecorator; |
@@ -15,2 +15,3 @@ "use strict"; | ||
const provider_declarations_1 = require("./provider.declarations"); | ||
const recaptcha_request_resolver_1 = require("./services/recaptcha-request.resolver"); | ||
let GoogleRecaptchaModule = GoogleRecaptchaModule_1 = class GoogleRecaptchaModule { | ||
@@ -21,2 +22,3 @@ static forRoot(options) { | ||
google_recaptcha_validator_1.GoogleRecaptchaValidator, | ||
recaptcha_request_resolver_1.RecaptchaRequestResolver, | ||
{ | ||
@@ -41,2 +43,3 @@ provide: provider_declarations_1.RECAPTCHA_OPTIONS, | ||
google_recaptcha_validator_1.GoogleRecaptchaValidator, | ||
recaptcha_request_resolver_1.RecaptchaRequestResolver, | ||
...this.createAsyncProviders(options) | ||
@@ -43,0 +46,0 @@ ]; |
@@ -5,8 +5,10 @@ import { CanActivate, ExecutionContext } from '@nestjs/common'; | ||
import { Reflector } from '@nestjs/core'; | ||
import { RecaptchaRequestResolver } from '../services/recaptcha-request.resolver'; | ||
export declare class GoogleRecaptchaGuard implements CanActivate { | ||
private readonly validator; | ||
private readonly reflector; | ||
private readonly requestResolver; | ||
private readonly options; | ||
constructor(validator: GoogleRecaptchaValidator, reflector: Reflector, options: GoogleRecaptchaGuardOptions); | ||
constructor(validator: GoogleRecaptchaValidator, reflector: Reflector, requestResolver: RecaptchaRequestResolver, options: GoogleRecaptchaGuardOptions); | ||
canActivate(context: ExecutionContext): Promise<true | never>; | ||
} |
@@ -21,10 +21,13 @@ "use strict"; | ||
const core_1 = require("@nestjs/core"); | ||
const recaptcha_request_resolver_1 = require("../services/recaptcha-request.resolver"); | ||
const application_type_1 = require("../enums/application-type"); | ||
let GoogleRecaptchaGuard = class GoogleRecaptchaGuard { | ||
constructor(validator, reflector, options) { | ||
constructor(validator, reflector, requestResolver, options) { | ||
this.validator = validator; | ||
this.reflector = reflector; | ||
this.requestResolver = requestResolver; | ||
this.options = options; | ||
} | ||
async canActivate(context) { | ||
const request = context.switchToHttp().getRequest(); | ||
const request = this.requestResolver.resolve(context, this.options.applicationType || application_type_1.ApplicationType.Rest); | ||
const skip = typeof this.options.skipIf === 'function' | ||
@@ -49,7 +52,8 @@ ? await this.options.skipIf(request) | ||
common_1.Injectable(), | ||
__param(2, common_1.Inject(provider_declarations_1.RECAPTCHA_OPTIONS)), | ||
__param(3, common_1.Inject(provider_declarations_1.RECAPTCHA_OPTIONS)), | ||
__metadata("design:paramtypes", [google_recaptcha_validator_1.GoogleRecaptchaValidator, | ||
core_1.Reflector, Object]) | ||
core_1.Reflector, | ||
recaptcha_request_resolver_1.RecaptchaRequestResolver, Object]) | ||
], GoogleRecaptchaGuard); | ||
exports.GoogleRecaptchaGuard = GoogleRecaptchaGuard; | ||
//# sourceMappingURL=google-recaptcha.guard.js.map |
@@ -6,3 +6,4 @@ export { Recaptcha } from './decorators/recaptcha'; | ||
export { ErrorCode } from './enums/error-code'; | ||
export { ApplicationType } from './enums/application-type'; | ||
export { GoogleRecaptchaNetwork } from './enums/google-recaptcha-network'; | ||
export { GoogleRecaptchaException } from './exceptions/google-recaptcha.exception'; |
@@ -11,2 +11,4 @@ "use strict"; | ||
Object.defineProperty(exports, "ErrorCode", { enumerable: true, get: function () { return error_code_1.ErrorCode; } }); | ||
var application_type_1 = require("./enums/application-type"); | ||
Object.defineProperty(exports, "ApplicationType", { enumerable: true, get: function () { return application_type_1.ApplicationType; } }); | ||
var google_recaptcha_network_1 = require("./enums/google-recaptcha-network"); | ||
@@ -13,0 +15,0 @@ Object.defineProperty(exports, "GoogleRecaptchaNetwork", { enumerable: true, get: function () { return google_recaptcha_network_1.GoogleRecaptchaNetwork; } }); |
import { RecaptchaResponseProvider } from '../types'; | ||
import { ApplicationType } from '../enums/application-type'; | ||
export interface GoogleRecaptchaGuardOptions { | ||
response: RecaptchaResponseProvider; | ||
applicationType?: ApplicationType; | ||
skipIf?: boolean | ((request: any) => boolean | Promise<boolean>); | ||
} |
/// <reference types="node" /> | ||
import * as https from "https"; | ||
import { GoogleRecaptchaNetwork } from "../enums/google-recaptcha-network"; | ||
import * as https from 'https'; | ||
import { GoogleRecaptchaNetwork } from '../enums/google-recaptcha-network'; | ||
export interface GoogleRecaptchaValidatorOptions { | ||
@@ -5,0 +5,0 @@ secretKey: string; |
{ | ||
"name": "@nestlab/google-recaptcha", | ||
"version": "1.2.1", | ||
"version": "1.2.2", | ||
"description": "Google recaptcha module for NestJS.", | ||
@@ -15,3 +15,4 @@ "keywords": [ | ||
"nestjs captcha", | ||
"nestjs recaptcha" | ||
"nestjs recaptcha", | ||
"graphql" | ||
], | ||
@@ -22,3 +23,4 @@ "private": false, | ||
"build": "rimraf dist && tsc && cp package.json dist && cp README.md dist && cp LICENSE dist && cp CONTRIBUTING.md dist", | ||
"test": "jest" | ||
"test": "jest", | ||
"test:cov": "jest --coverage" | ||
}, | ||
@@ -42,4 +44,6 @@ "repository": { | ||
"@nestjs/core": "^6.0.0", | ||
"@nestjs/graphql": "^7.9.8", | ||
"@nestjs/platform-express": "^6.11.11", | ||
"@nestjs/testing": "^6.11.11", | ||
"@types/express": "^4.17.11", | ||
"@types/jest": "^24.9.1", | ||
@@ -62,2 +66,5 @@ "@types/node": "^12.12.14", | ||
"rootDir": ".", | ||
"roots": [ | ||
"<rootDir>/test" | ||
], | ||
"testRegex": ".spec.ts$", | ||
@@ -68,4 +75,7 @@ "transform": { | ||
"coverageDirectory": "./coverage", | ||
"testEnvironment": "node" | ||
"testEnvironment": "node", | ||
"collectCoverageFrom": [ | ||
"src/**/*.ts" | ||
] | ||
} | ||
} |
@@ -8,2 +8,4 @@ # Google recaptcha module | ||
- [Usage](#usage) | ||
- [Rest](#rest) | ||
- [GraphQL](#graphql) | ||
- [Error handling](#error-handling) | ||
@@ -20,4 +22,11 @@ | ||
For using application type GraphQL `ApplicationType.GraphQL` you need to install `@nestjs/graphql`. | ||
``` | ||
$ npm i @nestjs/graphql | ||
``` | ||
## Configuration | ||
**Configuration for REST application** | ||
```typescript | ||
@@ -39,11 +48,36 @@ @Module({ | ||
**Configuration for GraphQL application** | ||
```typescript | ||
@Module({ | ||
imports: [ | ||
GoogleRecaptchaModule.forRoot({ | ||
secretKey: process.env.GOOGLE_RECAPTCHA_SECRET_KEY, | ||
response: req => (req: IncomingMessage) => (req.headers.recaptcha || '').toString(), | ||
skipIf: process.env.NODE_ENV !== 'production', | ||
network: GoogleRecaptchaNetwork.Recaptcha, | ||
applicationType: ApplicationType.GraphQL, | ||
agent: null | ||
}) | ||
], | ||
}) | ||
export class AppModule { | ||
} | ||
``` | ||
**Tip: header names transforming to lower case.** | ||
**For example:** If you send 'Recaptcha' header then use `(req) => req.headers.recaptcha` | ||
**Configuration options** | ||
| Property | Description | | ||
|-------------|-------------| | ||
| `secretKey` | **Required.**<br> Type: `string`<br> Google recaptcha secret key | | ||
| `response` | **Required.**<br> Type: `(request) => string`<br> Function that returns response (recaptcha token) by request | | ||
| `skipIf` | Optional.<br> Type: `boolean` \| `(request) => boolean \| Promise<boolean>` <br> Function that returns true if you allow the request to skip the recaptcha verification. Useful for involing other check methods (e.g. custom privileged API key) or for development or testing | | ||
| `network` | Optional.<br> Type: `GoogleRecaptchaNetwork` \| `boolean`<br> Default: `GoogleRecaptchaNetwork.Google` <br> If your server has trouble connecting to https://google.com then you can set networks:<br> `GoogleRecaptchaNetwork.Google` = 'https://www.google.com/recaptcha/api/siteverify'<br>`GoogleRecaptchaNetwork.Recaptcha` = 'https://recaptcha.net/recaptcha/api/siteverify'<br> or set any api url | | ||
| `agent` | Optional.<br> Type: `https.Agent`<br> If you need to use an agent | | ||
| Property | Description | | ||
|-------------------|-------------| | ||
| `secretKey` | **Required.**<br> Type: `string`<br> Google recaptcha secret key | | ||
| `response` | **Required.**<br> Type: `(request) => string`<br> Function that returns response (recaptcha token) by request | | ||
| `skipIf` | Optional.<br> Type: `boolean` \| `(request) => boolean \| Promise<boolean>` <br> Function that returns true if you allow the request to skip the recaptcha verification. Useful for involing other check methods (e.g. custom privileged API key) or for development or testing | | ||
| `network` | Optional.<br> Type: `GoogleRecaptchaNetwork` \| `boolean`<br> Default: `GoogleRecaptchaNetwork.Google` <br> If your server has trouble connecting to https://google.com then you can set networks:<br> `GoogleRecaptchaNetwork.Google` = 'https://www.google.com/recaptcha/api/siteverify'<br>`GoogleRecaptchaNetwork.Recaptcha` = 'https://recaptcha.net/recaptcha/api/siteverify'<br> or set any api url | | ||
| `applicationType` | Optional.<br> Type: `ApplicationType` <br> Default: `ApplicationType.Rest` <br> Application type affect on type of request argument on `response` provider function <br> Request types:<br> `ApplicationType.Rest` - `(req: express.Request \| fastify.Request) => string \| Promise<string>` <br> `ApplicationType.GraphQL` - `(req: http.IncommingMessage) => string \| Promise<string>` | | ||
| `agent` | Optional.<br> Type: `https.Agent`<br> If you need to use an agent | | ||
@@ -68,2 +102,4 @@ If you want import configs from your [ConfigService](https://docs.nestjs.com/techniques/configuration#getting-started) via [custom getter function](https://docs.nestjs.com/techniques/configuration#custom-getter-functions) that will return `GoogleRecaptchaModuleOptions` object. | ||
### Rest | ||
Use `@Recaptcha` decorator to protect your endpoints. | ||
@@ -114,2 +150,37 @@ | ||
### GraphQL | ||
Use `@Recaptcha` decorator to protect your resolver. | ||
```typescript | ||
@Recaptcha() | ||
@Resolver(of => Recipe) | ||
export class RecipesResolver { | ||
@Query(returns => Recipe) | ||
async recipe(@Args('id') id: string): Promise<Recipe> { | ||
// TODO: Your implementation. | ||
} | ||
} | ||
``` | ||
You can override default property that contain recaptcha for specific query, mutation or subscription. | ||
```typescript | ||
@Recaptcha() | ||
@Resolver(of => Recipe) | ||
export class RecipesResolver { | ||
@Query(returns => Recipe) | ||
async recipe(@Args('id') id: string): Promise<Recipe> { | ||
// TODO: Your implementation. | ||
} | ||
// Overridden default header. This query using X-Recaptcha header | ||
@Recaptcha((req: IncomingMessage) => (req.headers['x-recaptcha'] || '').toString()) | ||
@Query(returns => [Recipe]) | ||
recipes(@Args() recipesArgs: RecipesArgs): Promise<Recipe[]> { | ||
// TODO: Your implementation. | ||
} | ||
} | ||
``` | ||
## Error handling | ||
@@ -116,0 +187,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
43767
52
454
219
15
1