// (C) Copyright 2015 Moodle Pty Ltd. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import { Component, Input, OnDestroy } from '@angular/core'; import { ModalController } from '@singletons/core.singletons'; /** * Component to display a the recaptcha in a modal. */ @Component({ selector: 'core-recaptcha-modal', templateUrl: 'core-recaptchamodal.html', }) export class CoreRecaptchaModalComponent implements OnDestroy { @Input() recaptchaUrl?: string; expired = false; value = ''; protected messageListenerFunction: (event: MessageEvent) => Promise; constructor() { // Listen for messages from the iframe. this.messageListenerFunction = this.onIframeMessage.bind(this); window.addEventListener('message', this.messageListenerFunction); } /** * Close modal. */ closeModal(): void { ModalController.instance.dismiss({ expired: this.expired, value: this.value, }); } /** * The iframe with the recaptcha was loaded. * * @param iframe Iframe element. */ loaded(iframe: HTMLIFrameElement): void { // Search the iframe content. const contentWindow = iframe?.contentWindow; if (contentWindow) { try { // Set the callbacks we're interested in. contentWindow['recaptchacallback'] = this.onRecaptchaCallback.bind(this); contentWindow['recaptchaexpiredcallback'] = this.onRecaptchaExpiredCallback.bind(this); } catch (error) { // Cannot access the window. } } } /** * Treat an iframe message event. * * @param event Event. * @return Promise resolved when done. */ protected async onIframeMessage(event: MessageEvent): Promise { if (!event.data || event.data.environment != 'moodleapp' || event.data.context != 'recaptcha') { return; } switch (event.data.action) { case 'callback': this.onRecaptchaCallback(event.data.value); break; case 'expired': this.onRecaptchaExpiredCallback(); break; default: break; } } /** * Recapcha callback called. * * @param value Value received. */ protected onRecaptchaCallback(value: string): void { this.expired = false; this.value = value; this.closeModal(); } /** * Recapcha expired callback called. */ protected onRecaptchaExpiredCallback(): void { this.expired = true; this.value = ''; } /** * Component destroyed. */ ngOnDestroy(): void { window.removeEventListener('message', this.messageListenerFunction); } }