ng-recaptcha
Advanced tools
Comparing version 13.1.0 to 13.2.0
@@ -1,3 +0,3 @@ | ||
<a name="13.1.0"></a> | ||
# [13.1.0](https://github.com/DethAriel/ng-recaptcha/compare/v13.0.0...v13.1.0) (2023-11-24) | ||
<a name="13.2.0"></a> | ||
# [13.2.0](https://github.com/DethAriel/ng-recaptcha/compare/v13.1.0...v13.2.0) (2023-11-25) | ||
@@ -7,6 +7,14 @@ | ||
* **component:** load recaptcha script using code compatible with trusted types ([88d257b](https://github.com/DethAriel/ng-recaptcha/commit/88d257b)), closes [#304](https://github.com/DethAriel/ng-recaptcha/issues/304) | ||
* **component:** add a new `RECAPTCHA_LOADER_OPTIONS` injection token as a way of manipulating script load parameters (such as base URL, language, trusted types, WAF, etc) ([b3c7213](https://github.com/DethAriel/ng-recaptcha/commit/b3c7213)) | ||
<a name="13.1.0"></a> | ||
# [13.1.0](https://github.com/DethAriel/ng-recaptcha/compare/v13.0.0...v13.1.0) (2023-11-24) | ||
### Features | ||
- **component:** load recaptcha script using code compatible with trusted types ([88d257b](https://github.com/DethAriel/ng-recaptcha/commit/88d257b)), closes [#304](https://github.com/DethAriel/ng-recaptcha/issues/304) | ||
<a name="13.0.0"></a> | ||
@@ -13,0 +21,0 @@ |
@@ -9,2 +9,2 @@ export { RecaptchaComponent, RecaptchaErrorParameters } from "./lib/recaptcha.component"; | ||
export { RecaptchaValueAccessorDirective } from "./lib/recaptcha-value-accessor.directive"; | ||
export { RECAPTCHA_LANGUAGE, RECAPTCHA_BASE_URL, RECAPTCHA_NONCE, RECAPTCHA_SETTINGS, RECAPTCHA_V3_SITE_KEY, } from "./lib/tokens"; | ||
export { RECAPTCHA_LANGUAGE, RECAPTCHA_BASE_URL, RECAPTCHA_NONCE, RECAPTCHA_SETTINGS, RECAPTCHA_V3_SITE_KEY, RECAPTCHA_LOADER_OPTIONS, RecaptchaLoaderOptions, } from "./lib/tokens"; |
/// <reference types="grecaptcha" /> | ||
import { RecaptchaLoaderOptions } from "./tokens"; | ||
declare global { | ||
interface Window { | ||
ng2recaptchaloaded: () => void; | ||
ng2recaptchaloaded?(): void; | ||
} | ||
@@ -10,3 +11,6 @@ } | ||
}; | ||
declare function loadScript(renderMode: RenderMode, onLoaded: (grecaptcha: ReCaptchaV2.ReCaptcha) => void, { url, lang, nonce }?: { | ||
declare function loadScript(renderMode: RenderMode, onBeforeLoad: (url: URL) => { | ||
url: URL; | ||
nonce?: string; | ||
}, onLoaded: (grecaptcha: ReCaptchaV2.ReCaptcha) => void, { url, lang, nonce }?: { | ||
url?: string; | ||
@@ -16,5 +20,10 @@ lang?: string; | ||
}): void; | ||
declare function newLoadScript({ v3SiteKey, onBeforeLoad, onLoaded, }: { | ||
v3SiteKey: string | undefined; | ||
onLoaded(recaptcha: ReCaptchaV2.ReCaptcha): void; | ||
} & Pick<Required<RecaptchaLoaderOptions>, "onBeforeLoad">): void; | ||
export declare const loader: { | ||
loadScript: typeof loadScript; | ||
newLoadScript: typeof newLoadScript; | ||
}; | ||
export {}; |
/// <reference types="grecaptcha" /> | ||
import { Observable } from "rxjs"; | ||
import { RecaptchaLoaderOptions } from "./tokens"; | ||
import * as i0 from "@angular/core"; | ||
@@ -13,14 +14,16 @@ export declare class RecaptchaLoaderService { | ||
/** @internal */ | ||
private language; | ||
private language?; | ||
/** @internal */ | ||
private baseUrl; | ||
private baseUrl?; | ||
/** @internal */ | ||
private nonce; | ||
private nonce?; | ||
/** @internal */ | ||
private v3SiteKey; | ||
constructor(platformId: Object, language?: string, baseUrl?: string, nonce?: string, v3SiteKey?: string); | ||
private v3SiteKey?; | ||
/** @internal */ | ||
private options?; | ||
constructor(platformId: Object, language?: string, baseUrl?: string, nonce?: string, v3SiteKey?: string, options?: RecaptchaLoaderOptions); | ||
/** @internal */ | ||
private init; | ||
static ɵfac: i0.ɵɵFactoryDeclaration<RecaptchaLoaderService, [null, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }]>; | ||
static ɵfac: i0.ɵɵFactoryDeclaration<RecaptchaLoaderService, [null, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }]>; | ||
static ɵprov: i0.ɵɵInjectableDeclaration<RecaptchaLoaderService>; | ||
} |
import { NgZone } from "@angular/core"; | ||
import { Observable } from "rxjs"; | ||
import { RecaptchaLoaderService } from "./recaptcha-loader.service"; | ||
import * as i0 from "@angular/core"; | ||
@@ -31,5 +32,4 @@ export interface OnExecuteData { | ||
export declare class ReCaptchaV3Service { | ||
recaptchaLoader: RecaptchaLoaderService; | ||
/** @internal */ | ||
private readonly isBrowser; | ||
/** @internal */ | ||
private readonly siteKey; | ||
@@ -41,8 +41,2 @@ /** @internal */ | ||
/** @internal */ | ||
private nonce; | ||
/** @internal */ | ||
private language?; | ||
/** @internal */ | ||
private baseUrl; | ||
/** @internal */ | ||
private grecaptcha; | ||
@@ -57,3 +51,3 @@ /** @internal */ | ||
private onExecuteErrorObservable; | ||
constructor(zone: NgZone, siteKey: string, platformId: Object, baseUrl?: string, nonce?: string, language?: string); | ||
constructor(zone: NgZone, recaptchaLoader: RecaptchaLoaderService, siteKey: string); | ||
get onExecute(): Observable<OnExecuteData>; | ||
@@ -77,6 +71,4 @@ get onExecuteError(): Observable<OnExecuteErrorData>; | ||
private init; | ||
/** @internal */ | ||
private onLoadComplete; | ||
static ɵfac: i0.ɵɵFactoryDeclaration<ReCaptchaV3Service, [null, null, null, { optional: true; }, { optional: true; }, { optional: true; }]>; | ||
static ɵfac: i0.ɵɵFactoryDeclaration<ReCaptchaV3Service, never>; | ||
static ɵprov: i0.ɵɵInjectableDeclaration<ReCaptchaV3Service>; | ||
} |
@@ -13,10 +13,10 @@ /// <reference types="grecaptcha" /> | ||
id: string; | ||
siteKey: string; | ||
theme: ReCaptchaV2.Theme; | ||
type: ReCaptchaV2.Type; | ||
size: ReCaptchaV2.Size; | ||
tabIndex: number; | ||
badge: ReCaptchaV2.Badge; | ||
siteKey?: string; | ||
theme?: ReCaptchaV2.Theme; | ||
type?: ReCaptchaV2.Type; | ||
size?: ReCaptchaV2.Size; | ||
tabIndex?: number; | ||
badge?: ReCaptchaV2.Badge; | ||
errorMode: "handled" | "default"; | ||
resolved: EventEmitter<string>; | ||
resolved: EventEmitter<string | null>; | ||
/** | ||
@@ -23,0 +23,0 @@ * @deprecated `(error) output will be removed in the next major version. Use (errored) instead |
@@ -0,7 +1,116 @@ | ||
/// <reference types="grecaptcha" /> | ||
import { InjectionToken } from "@angular/core"; | ||
import { RecaptchaSettings } from "./recaptcha-settings"; | ||
/** @deprecated Use `LOADER_OPTIONS` instead. See `RecaptchaLoaderOptions.onBeforeLoad` */ | ||
export declare const RECAPTCHA_LANGUAGE: InjectionToken<string>; | ||
/** @deprecated Use `LOADER_OPTIONS` instead. See `RecaptchaLoaderOptions.onBeforeLoad` */ | ||
export declare const RECAPTCHA_BASE_URL: InjectionToken<string>; | ||
/** @deprecated Use `LOADER_OPTIONS` instead. See `RecaptchaLoaderOptions.onBeforeLoad` */ | ||
export declare const RECAPTCHA_NONCE: InjectionToken<string>; | ||
export declare const RECAPTCHA_SETTINGS: InjectionToken<RecaptchaSettings>; | ||
export declare const RECAPTCHA_V3_SITE_KEY: InjectionToken<string>; | ||
/** | ||
* Specifies the options for loading the reCAPTCHA script tag. | ||
*/ | ||
export type RecaptchaLoaderOptions = { | ||
/** | ||
* Invoked before the `<script>` tag is appended to the DOM. | ||
* Use this function as an opportunity to set `nonce`, as well as modify the URL of the tag. | ||
* | ||
* Use the `url.searchParams` to set additional query string attributes (including reCAPTCHA language), | ||
* or use an entirely different base URL altogether. | ||
* | ||
* The URL that you provide will then properly set the `"render"` and `"onload"` attributes which are required for proper `ng-recaptcha` wire-up. | ||
* | ||
* @param url the current URL that was composed. Either modify it in-place, or return a completely new URL. | ||
* @returns the final URL that is going to be used as the `src` for the `<script>` tag, along with (optionally) a nonce. | ||
* | ||
* @example | ||
* Provide nonce: | ||
* ```ts | ||
* { | ||
* provide: RECAPTCHA_LOADER_OPTIONS, | ||
* useValue: { | ||
* onBeforeLoad(url) { | ||
* return { | ||
* url, | ||
* nonce: "YOUR_NONCE" | ||
* }; | ||
* } | ||
* } | ||
* } | ||
* ``` | ||
* | ||
* Set the reCAPTCHA language: | ||
* ```ts | ||
* { | ||
* provide: RECAPTCHA_LOADER_OPTIONS, | ||
* useValue: { | ||
* onBeforeLoad(url) { | ||
* url.searchParams.set("hl", "en-GB") | ||
* | ||
* return { url }; | ||
* } | ||
* } | ||
* } | ||
* ``` | ||
* | ||
* Use a different base URL for loading reCAPTCHA | ||
* ```ts | ||
* { | ||
* provide: RECAPTCHA_LOADER_OPTIONS, | ||
* useValue: { | ||
* onBeforeLoad(_url) { | ||
* const chinaCompatibleUrl = new URL("https://www.recaptcha.net/recaptcha/api.js"); | ||
* // optionally, set the locale: | ||
* // chinaCompatibleUrl.searchParams.set("hl", "zh-CN"); | ||
* | ||
* return { | ||
* url: chinaCompatibleUrl | ||
* }; | ||
* } | ||
* } | ||
* } | ||
* ``` | ||
*/ | ||
onBeforeLoad?(url: URL): { | ||
url: URL; | ||
nonce?: string; | ||
}; | ||
/** | ||
* Allows you to change the `grecaptcha` that the `ng-recaptcha` will be relying on. | ||
* This method is useful when you need to use `grecaptcha.enterprise` instead of the base `grecaptcha` | ||
* | ||
* @param recaptcha the value of `window.grecaptcha` upon script load. | ||
* @returns the {ReCaptchaV2.ReCaptcha} instance that the `ng-recaptcha` lib will use. | ||
* | ||
* @example | ||
* Using the Enterprise version of `grecaptcha`: | ||
* | ||
* ```ts | ||
* { | ||
* provide: RECAPTCHA_LOADER_OPTIONS, | ||
* useValue: { | ||
* onBeforeLoad() { | ||
* const recaptchaEnterpriseUrl = new URL("https://www.google.com/recaptcha/enterprise.js"); | ||
* // optionally, if you're using the reCAPTCHA session-tokens, set the `&waf=session` param, | ||
* // see https://cloud.google.com/recaptcha-enterprise/docs/implement-waf-ca#session-token | ||
* // recaptchaEnterpriseUrl.searchParams.set("waf", "session"); | ||
* | ||
* return { | ||
* url: recaptchaEnterpriseUrl, | ||
* } | ||
* }, | ||
* onLoaded(recaptcha) { | ||
* return recaptcha.enterprise; | ||
* } | ||
* } | ||
* } | ||
* ``` | ||
*/ | ||
onLoaded?(recaptcha: ReCaptchaV2.ReCaptcha): ReCaptchaV2.ReCaptcha; | ||
}; | ||
/** | ||
* See the documentation for `RecaptchaLoaderOptions`. | ||
*/ | ||
export declare const RECAPTCHA_LOADER_OPTIONS: InjectionToken<RecaptchaLoaderOptions>; |
{ | ||
"name": "ng-recaptcha", | ||
"description": "Angular component for Google reCAPTCHA", | ||
"version": "13.1.0", | ||
"version": "13.2.0", | ||
"author": "Ruslan Arkhipau <dethariel@gmail.com>", | ||
@@ -22,3 +22,3 @@ "license": "MIT", | ||
"dependencies": { | ||
"@types/grecaptcha": "^3.0.3", | ||
"@types/grecaptcha": "^3.0.7", | ||
"tslib": "^2.2.0" | ||
@@ -25,0 +25,0 @@ }, |
@@ -36,2 +36,3 @@ # Angular component for Google reCAPTCHA | ||
- [Listening for all actions with reCAPTCHA v3](#example-v3-all-actions) | ||
- [Loading reCAPTCHA keys asynchronously](#async-config-load) | ||
- [Hiding reCAPTCHA badge](#hide-recaptcha-badge) | ||
@@ -246,3 +247,3 @@ | ||
(which is beyond the scope of this lib). | ||
But you can override this behavior and provide a specific language to use. | ||
But you can override this behavior and provide a specific language to use by setting the `"hl"` search param in the `onBeforeLoad` hook. | ||
Note, that the language setting is **global**, and cannot be set on a per-captcha basis. | ||
@@ -254,3 +255,3 @@ | ||
import { LOCALE_ID } from "@angular/core"; | ||
import { RECAPTCHA_LANGUAGE } from "ng-recaptcha"; | ||
import { RECAPTCHA_LOADER_OPTIONS } from "ng-recaptcha"; | ||
@@ -260,4 +261,10 @@ @NgModule({ | ||
{ | ||
provide: RECAPTCHA_LANGUAGE, | ||
useFactory: (locale: string) => locale, | ||
provide: RECAPTCHA_LOADER_OPTIONS, | ||
useFactory: (locale: string) => ({ | ||
onBeforeLoad(url) { | ||
url.searchParams.set("hl", locale); | ||
return { url }; | ||
}, | ||
}), | ||
deps: [LOCALE_ID], | ||
@@ -273,3 +280,3 @@ }, | ||
```typescript | ||
import { RECAPTCHA_LANGUAGE } from "ng-recaptcha"; | ||
import { RECAPTCHA_LOADER_OPTIONS } from "ng-recaptcha"; | ||
@@ -279,4 +286,10 @@ @NgModule({ | ||
{ | ||
provide: RECAPTCHA_LANGUAGE, | ||
useValue: "fr", // use French language | ||
provide: RECAPTCHA_LOADER_OPTIONS, | ||
useValue: { | ||
onBeforeLoad(url) { | ||
url.searchParams.set("hl", "fr"); // use French language | ||
return { url }; | ||
}, | ||
}, | ||
}, | ||
@@ -481,6 +494,6 @@ ], | ||
Since `"google.com"` domain might be unavailable in some countries, reCAPTCHA core team has a solution for that - using `"recaptcha.net"` domain. You can configure the component to use that by providing the `RECAPTCHA_BASE_URL` token, for example: | ||
Since `"google.com"` domain might be unavailable in some countries, reCAPTCHA core team has a solution for that - using `"recaptcha.net"` domain. You can configure the component to use that by using the `onBeforeLoad` hook of `RECAPTCHA_LOADER_OPTIONS`, for example: | ||
```javascript | ||
import { RECAPTCHA_BASE_URL } from "ng-recaptcha"; | ||
import { RECAPTCHA_LOADER_OPTIONS } from "ng-recaptcha"; | ||
@@ -490,4 +503,10 @@ @NgModule({ | ||
{ | ||
provide: RECAPTCHA_BASE_URL, | ||
useValue: "https://recaptcha.net/recaptcha/api.js", // use recaptcha.net script source for some of our users | ||
provide: RECAPTCHA_LOADER_OPTIONS, | ||
useValue: { | ||
onBeforeLoad(_url) { | ||
return { | ||
url: new URL("https://www.recaptcha.net/recaptcha/api.js"), // use recaptcha.net script source for some of our users | ||
}; | ||
}, | ||
}, | ||
}, | ||
@@ -501,6 +520,6 @@ ], | ||
Per [reCAPTCHA FAQ on CSP](https://developers.google.com/recaptcha/docs/faq#im-using-content-security-policy-csp-on-my-website-how-can-i-configure-it-to-work-with-recaptcha), the recommended approach for that is to supply nonce to the script tag. This is possible by providing the `RECAPTCHA_NONCE` token, for example: | ||
Per [reCAPTCHA FAQ on CSP](https://developers.google.com/recaptcha/docs/faq#im-using-content-security-policy-csp-on-my-website-how-can-i-configure-it-to-work-with-recaptcha), the recommended approach for that is to supply nonce to the script tag. This is possible by providing the nonce as part of the `onBeforeLoad` hook of `RECAPTCHA_LOADER_OPTIONS`, for example | ||
```javascript | ||
import { RECAPTCHA_NONCE } from "ng-recaptcha"; | ||
import { RECAPTCHA_LOADER_OPTIONS } from "ng-recaptcha"; | ||
@@ -510,4 +529,11 @@ @NgModule({ | ||
{ | ||
provide: RECAPTCHA_NONCE, | ||
useValue: "<YOUR_NONCE_VALUE>", | ||
provide: RECAPTCHA_LOADER_OPTIONS, | ||
useValue: { | ||
onBeforeLoad(_url) { | ||
return { | ||
url, | ||
nonce: "<YOUR_NONCE_VALUE>", | ||
}; | ||
}, | ||
}, | ||
}, | ||
@@ -514,0 +540,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
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
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
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
207535
1474
648
Updated@types/grecaptcha@^3.0.7