{"version":3,"file":"chunk-lybijbjg.js","sources":["packages/vanilla/lib/features/recaptcha/src/recaptcha.client-config.ts","packages/vanilla/lib/features/recaptcha/src/recaptcha-enterprise.service.ts","packages/vanilla/lib/features/recaptcha/src/recaptcha.models.ts","packages/vanilla/lib/features/recaptcha/src/recaptcha-enterprise-bootstrap.service.ts","packages/vanilla/lib/features/recaptcha/src/recaptcha.feature.ts","packages/vanilla/lib/features/recaptcha/src/recaptcha-enterprise.component.ts","packages/vanilla/lib/features/recaptcha/src/recaptcha-enterprise.html","packages/vanilla/lib/features/recaptcha/src/recaptcha.html","packages/vanilla/lib/features/recaptcha/src/recaptcha.component.ts","packages/vanilla/lib/features/recaptcha/src/recaptcha-value-accessor.directive.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\nimport { ClientConfigProductName, LazyClientConfig, LazyClientConfigBase, LazyClientConfigService } from '@frontend/vanilla/core';\n\n/**\n * @stable\n */\n@LazyClientConfig({ key: 'vnReCaptcha', product: ClientConfigProductName.SF })\n@Injectable({\n providedIn: 'root',\n deps: [LazyClientConfigService],\n useFactory: reCaptchaConfigFactory,\n})\nexport class ReCaptchaConfig extends LazyClientConfigBase {\n enterpriseSiteKey: string;\n theme: string;\n verificationMessage: string;\n areas: { [area: string]: boolean };\n instrumentationOnPageLoad: boolean;\n}\n\nexport function reCaptchaConfigFactory(service: LazyClientConfigService) {\n return service.get(ReCaptchaConfig);\n}\n","import { DOCUMENT } from '@angular/common';\nimport { Injectable, NgZone, inject } from '@angular/core';\n\nimport { Logger, Page } from '@frontend/vanilla/core';\nimport { BehaviorSubject, Subject, first } from 'rxjs';\n\nimport { ReCaptchaConfig } from './recaptcha.client-config';\nimport { RecaptchaProperties } from './recaptcha.models';\n\nexport const CALLBACK = 'reCaptchaLoadCallback';\n\n/**\n * @stable\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class RecaptchaEnterpriseService {\n action: string;\n\n readonly scriptLoaded: BehaviorSubject = new BehaviorSubject(false);\n readonly success: Subject = new Subject();\n readonly recaptchaToken: Subject = new Subject();\n private readonly _doc = inject(DOCUMENT);\n\n private reCaptchaApi: any;\n private activeRecaptchaId: any;\n\n constructor(\n private zone: NgZone,\n private page: Page,\n private recaptchaConfig: ReCaptchaConfig,\n private logger: Logger,\n ) {}\n\n initReCaptchaAPI() {\n if (!this.reCaptchaApi) {\n this.addGlobalFunction();\n this.addScript();\n }\n }\n\n /**\n * Executes the reCaptcha client api with siteKey when using automatic rendering or elementId on explicit rendering.\n */\n executeRecaptcha(action: string, key?: string) {\n this.zone.runOutsideAngular(() => {\n const normalizedAction = `${action}_${this.page.domain.replace(/\\./g, '').trim()}`;\n\n this.scriptLoaded.pipe(first((ready: boolean) => ready)).subscribe(() => {\n this.reCaptchaApi\n .execute(key ?? this.activeRecaptchaId, { action: normalizedAction })\n .then((token: string) => {\n this.logger.info(`Recaptcha token received from client api for action [${normalizedAction}]: `, token);\n this.recaptchaToken.next(token);\n })\n .catch((error: any) => {\n this.logger.errorRemote(\n `RecaptchaEnterprise script api failed to execute on client for action [${normalizedAction}]: `,\n error,\n );\n });\n });\n });\n }\n\n renderRecaptcha(containerElement: any): any {\n try {\n this.activeRecaptchaId = this.reCaptchaApi.render(containerElement, this.getCaptchaProperties());\n\n return this.activeRecaptchaId;\n } catch (error: any) {\n this.logger.errorRemote('Failed rendering reCAPTCHA.', error);\n }\n }\n\n resetCaptcha() {\n this.zone.runOutsideAngular(() => {\n this.reCaptchaApi.reset(this.activeRecaptchaId);\n });\n }\n\n private addGlobalFunction() {\n (window)[CALLBACK] = () => {\n this.reCaptchaApi = (window).grecaptcha.enterprise;\n this.reCaptchaApi.ready(() => {\n this.scriptLoaded.next(true);\n });\n };\n }\n\n private addScript() {\n const elementId = 'recaptcha-enterprise';\n\n if (this._doc.getElementById(elementId)) {\n return;\n }\n\n const script = this._doc.createElement('script');\n script.src = `https://www.google.com/recaptcha/enterprise.js?onload=${CALLBACK}&render=${this.recaptchaConfig.enterpriseSiteKey}&hl=${this.page.lang}`;\n script.id = 'recaptcha-enterprise';\n script.async = true;\n script.defer = true;\n this._doc.head.appendChild(script);\n }\n\n private onError(error: string) {\n this.logger.error(\n 'Error while loading reCaptcha. This is usually due to wrong or not configured EnterpriseSiteKey on Dynacon and Google console.',\n error,\n );\n }\n\n private onExpired() {\n this.logger.info('Recaptcha expired, reloading...');\n this.resetCaptcha();\n }\n\n private onSuccess(token: string) {\n this.success.next(token);\n }\n\n private getCaptchaProperties(): RecaptchaProperties {\n return {\n 'sitekey': this.recaptchaConfig.enterpriseSiteKey,\n 'theme': this.recaptchaConfig.theme,\n 'size': 'invisible',\n 'callback': this.onSuccess.bind(this),\n 'error-callback': this.onError.bind(this),\n 'expired-callback': this.onExpired.bind(this),\n };\n }\n}\n","/**\n * @stable\n */\nexport enum RecaptchaAction {\n PageLoad = 'pageLoad',\n AutoLogin = 'autoLogin',\n}\n\nexport interface RecaptchaProperties {\n 'sitekey': string;\n 'size': string;\n 'theme': string;\n 'callback': (token: string) => void;\n 'expired-callback': () => void;\n 'error-callback': (error: string) => void;\n}\n","import { Injectable } from '@angular/core';\n\nimport { LocationChangeEvent, NavigationService, OnFeatureInit } from '@frontend/vanilla/core';\nimport { first, firstValueFrom } from 'rxjs';\n\nimport { RecaptchaEnterpriseService } from './recaptcha-enterprise.service';\nimport { ReCaptchaConfig } from './recaptcha.client-config';\nimport { RecaptchaAction } from './recaptcha.models';\n\n@Injectable()\nexport class RecaptchaEnterpriseBootstrapService implements OnFeatureInit {\n constructor(\n private recaptchaConfig: ReCaptchaConfig,\n private recaptchaEnterpriseService: RecaptchaEnterpriseService,\n private navigationService: NavigationService,\n ) {}\n\n async onFeatureInit() {\n await firstValueFrom(this.recaptchaConfig.whenReady);\n\n if (this.recaptchaConfig.instrumentationOnPageLoad) {\n this.recaptchaEnterpriseService.initReCaptchaAPI();\n\n this.recaptchaEnterpriseService.scriptLoaded.pipe(first((ready: boolean) => ready)).subscribe(() => {\n this.recaptchaEnterpriseService.executeRecaptcha(RecaptchaAction.PageLoad, this.recaptchaConfig.enterpriseSiteKey);\n });\n\n this.navigationService.locationChange.subscribe((event: LocationChangeEvent) => {\n if (event.previousUrl !== event.nextUrl) {\n this.recaptchaEnterpriseService.executeRecaptcha(RecaptchaAction.PageLoad, this.recaptchaConfig.enterpriseSiteKey);\n }\n });\n }\n }\n}\n","import { runOnFeatureInit } from '@frontend/vanilla/core';\n\nimport { RecaptchaEnterpriseBootstrapService } from './recaptcha-enterprise-bootstrap.service';\n\nexport function provide() {\n return [runOnFeatureInit(RecaptchaEnterpriseBootstrapService)];\n}\n","import { Component, DestroyRef, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild, forwardRef, inject } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nimport { first } from 'rxjs';\n\nimport { RecaptchaEnterpriseService } from './recaptcha-enterprise.service';\n\n@Component({\n standalone: true,\n selector: 'vn-recaptcha-enterprise',\n templateUrl: 'recaptcha-enterprise.html',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n // eslint-disable-next-line @angular-eslint/no-forward-ref\n useExisting: forwardRef(() => RecaptchaEnterpriseComponent),\n multi: true,\n },\n ],\n})\nexport class RecaptchaEnterpriseComponent implements ControlValueAccessor, OnInit {\n @Input() action: string;\n @Output() success = new EventEmitter();\n\n @ViewChild('captchaWrapperElem', { static: true }) reCaptchaContainer: ElementRef;\n\n onChange: (val: string) => void;\n onTouched: () => void;\n\n private readonly reCaptchaEnterpriseService = inject(RecaptchaEnterpriseService);\n private readonly destroyRef = inject(DestroyRef);\n\n ngOnInit() {\n this.reCaptchaEnterpriseService.action = this.action;\n\n this.reCaptchaEnterpriseService.initReCaptchaAPI();\n\n this.reCaptchaEnterpriseService.scriptLoaded.pipe(first((ready: boolean) => ready)).subscribe(() => {\n this.reCaptchaEnterpriseService.renderRecaptcha(this.reCaptchaContainer.nativeElement);\n });\n\n this.reCaptchaEnterpriseService.success.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((token: string) => {\n this.success.next(token);\n });\n }\n\n registerOnChange(fn: (val: string) => void) {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void) {\n this.onTouched = fn;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n writeValue(_obj: any) {\n // This is intentional\n }\n\n execute() {\n this.reCaptchaEnterpriseService.executeRecaptcha(this.action);\n }\n\n reset() {\n this.reCaptchaEnterpriseService.resetCaptcha();\n }\n}\n","
\n","@if (isEnabled()) {\n \n}\n","import { CommonModule } from '@angular/common';\nimport { Component, EventEmitter, Input, OnInit, Output, ViewChild, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { Logger, Page, SharedFeaturesApiService } from '@frontend/vanilla/core';\nimport { BehaviorSubject, firstValueFrom } from 'rxjs';\nimport { filter, map, timeout } from 'rxjs/operators';\n\nimport { RecaptchaEnterpriseComponent } from './recaptcha-enterprise.component';\nimport { ReCaptchaConfig } from './recaptcha.client-config';\n\n/**\n * @whatItDoes Renders google reCaptcha.\n *\n * @howToUse\n * ### NEW - Basic reCAPTCHA Enterprise usage\n *\n * ```\n *
\n *\n * \n *