Skip to content

Commit

Permalink
fix: duplicate script injection when using multiple components (#31)
Browse files Browse the repository at this point in the history
chore: add test for duplicate script injection fix

fix: inject Document

chore: format
  • Loading branch information
yuskhan authored Jul 16, 2024
1 parent 3deb99b commit 5174532
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
19 changes: 19 additions & 0 deletions cypress/e2e/ngx-turnstile.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,23 @@ describe('tests the ngx-turnstile library', () => {
cy.wait(3000);
cy.contains('Value: XXXX.DUMMY.TOKEN.XXXX');
});

// visits multiple routes and makes sure script is not injected multiple times
it('Passes Visiting Multiple Routes Example', () => {
cy.visit(Cypress.env('reactiveFormUrl'));
cy.wait(3000);
cy.contains('Value: XXXX.DUMMY.TOKEN.XXXX');

cy.visit(Cypress.env('templateDrivenFormUrl'), {
onBeforeLoad(win) {
cy.spy(win.console, 'warn').as('consoleWarn');
},
});
cy.wait(3000);
cy.contains('Value: XXXX.DUMMY.TOKEN.XXXX');
cy.get('@consoleWarn').should(
'not.be.calledWith',
'[Cloudflare Turnstile] Turnstile already has been loaded. Was Turnstile imported multiple times?.',
);
});
});
19 changes: 16 additions & 3 deletions projects/ngx-turnstile/src/lib/ngx-turnstile.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import {
Output,
EventEmitter,
OnDestroy,
Inject,
} from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { TurnstileOptions } from './interfaces/turnstile-options';

declare global {
Expand All @@ -27,6 +29,7 @@ declare global {
}
}

const SCRIPT_ID = 'ngx-turnstile';
const CALLBACK_NAME = 'onloadTurnstileCallback';
type SupportedVersion = '0';

Expand All @@ -52,6 +55,7 @@ export class NgxTurnstileComponent implements AfterViewInit, OnDestroy {
constructor(
private elementRef: ElementRef<HTMLElement>,
private zone: NgZone,
@Inject(DOCUMENT) private document: Document,
) {}

private _getCloudflareTurnstileUrl(): string {
Expand Down Expand Up @@ -83,8 +87,6 @@ export class NgxTurnstileComponent implements AfterViewInit, OnDestroy {
},
};

const script = document.createElement('script');

window[CALLBACK_NAME] = () => {
if (!this.elementRef?.nativeElement) {
return;
Expand All @@ -96,10 +98,17 @@ export class NgxTurnstileComponent implements AfterViewInit, OnDestroy {
);
};

if (this.scriptLoaded()) {
window[CALLBACK_NAME]();
return;
}

const script = this.document.createElement('script');
script.src = `${this._getCloudflareTurnstileUrl()}?render=explicit&onload=${CALLBACK_NAME}`;
script.id = SCRIPT_ID;
script.async = true;
script.defer = true;
document.head.appendChild(script);
this.document.head.appendChild(script);
}

public reset(): void {
Expand All @@ -114,4 +123,8 @@ export class NgxTurnstileComponent implements AfterViewInit, OnDestroy {
window.turnstile.remove(this.widgetId);
}
}

public scriptLoaded(): boolean {
return !!this.document.getElementById(SCRIPT_ID);
}
}

0 comments on commit 5174532

Please sign in to comment.