Repository navigation
v1.3.0
v1.3.0 — Teach users what they missed
Until now, a user who fell for a simulated phishing page was redirected straight to the oops page. They learned that they failed, but not what they should have noticed. This release adds an interactive tutorial that inspects the page they fell for, walks them through the warning signs they missed, and then performs the same redirect.
It is off by default. Existing integrations behave exactly as before.
const ev = new ATSEvents({
apiKey: "YOUR_API_KEY",
tutorial: true,
});
ev.listen();What the tutorial explains
The page is scanned the moment the event fires, and every dangerous item found becomes its own step with the element highlighted in place.
- The address — not a generic warning, but why this URL should have raised suspicion: a raw IP, a lookalike built from special characters, a brand parked in a subdomain, a throwaway TLD, or an address long enough to push the real name out of sight. The part that decides ownership is highlighted, and the readout keeps the deceptive bits other tools hide, such as the
user@hosttrick and non-default ports. - Credential and card forms — recognised from labels, ARIA text and surrounding copy, so forms with no
<form>element and password fields typed astextare still caught. - Downloads — links and buttons that would have delivered a file.
- Links that lie — where the visible text and the real destination differ.
- Pressure tactics — the deadline or account-suspension threat is quoted back to the user in their own language.
- Brand impersonation — when a page presents itself as an organisation the address does not belong to.
- Permissions — microphone, camera, location, notifications, clipboard and browser extensions each get their own explanation of what was just granted.
Brand detection without a list
Rather than shipping a list that would always be out of date, the tutorial works out which organisation a page claims to be by scoring independent signals — the copyright line, og:site_name, logo alt text and file names, inline SVG wordmarks, the title and headings — and only names a brand once they agree. That works for organisations nobody bundled a list for, in any language.
If your campaign already knows what the landing page imitates, send it as ats_brand in the campaign token and that value is used instead of any guess.
Languages
Ten locales, each reviewed by a native speaker: en-US, ro-RO, es-ES, ca-ES, es-419 (also accepted as es-LATAM), pt-BR, pt-PT, fr-FR, de-DE, el-GR. The language comes from the locale option, then the campaign token, then the browser, falling back to en-US.
New options
| Option | Type | Default | Description |
|---|---|---|---|
tutorial |
boolean |
false |
Show the tutorial instead of redirecting immediately |
tutorialSkippable |
boolean |
true |
Show a skip link |
locale |
string |
auto | Force the tutorial language |
Smaller bundle
Source maps were being inlined as base64 into the shipped file, where they accounted for three quarters of every byte. They are now emitted as separate .map files, which browsers only fetch when devtools are open.
| Before | After | |
|---|---|---|
bundle.min.js |
244 KB | 190 KB |
| gzipped | ~73 KB | 61 KB |
The bundle is smaller than the previous release despite carrying the whole feature.
Reliability
The redirect is the one thing that must never be lost, so it is now guaranteed on every path. A throwing event subscriber, a failed page scan, or an overlay that the host page hides or removes all fall back to navigating. Since landing pages are attacker-authored, the overlay is checked after opening and the redirect happens anyway if it is not genuinely on screen.
Toolchain
Dependencies were updated: ESLint 10 (flat config), TypeScript 6,
@typescript-eslint 8, webpack-cli 7 and ua-parser-js 2.
Contributors should note that TypeScript stays on 6.x. TypeScript 7 is the Go rewrite and exposes a different JS API, which ts-loader cannot drive; moving to it would mean switching to a different loader.
There are no API changes for consumers of the package.