Repository navigation
Security
The full policy is SECURITY.md in the repo. This page is the part an integrator needs.
Use GitHub Security Advisories on the repo ("Report a vulnerability"), or email security@baryo.dev. Do not open a public issue for a vulnerability. The 2.x line is supported.
Progress is stored in the browser. Anyone can open the dev tools and set their XP to a million. The library cannot stop that, and no client-side library can.
What it does: saved state is validated on load, so an edited or corrupt save becomes valid numbers and plain records. It cannot crash the app, produce NaN XP, or write to Object.prototype.
What you do: if XP, a level or an achievement unlocks something of value (a discount, a prize, a leaderboard place), compute it on your server from events your server saw. Treat the client's numbers as display.
GameUI.showAchievement inserts icon with innerHTML, so an icon can be an <img> or an inline SVG. Every other field (name, description, xp) is inserted as text.
Never build icon from user input or from anything a user can influence. Define icons in your own code.
// fine
{ icon: '<img src="/icons/star.svg" alt="">' }
// never
{ icon: userProfile.avatarHtml }WebhookIntegration signs each request with HMAC-SHA256 when given a secret. In browser code, that secret ships to every player and can be read.
So the signature proves the request came from a copy of your app. It does not prove the payload is true. On the receiving end:
- Verify
X-Dopamine-Signatureagainst the raw request body, before parsing. A verification sample is on Plugin: Ecosystem. - Treat the payload as a claim by that player.
- Check anything that matters against your own records.
If you used dopaminejs-plugin-ecosystem before 2.0.0 with a secret, rotate it. The old "signature" was the secret itself, base64 encoded with the payload, sent on every request.
Game names, achievement ids and sound keys are looked up by own property. recordGame('__proto__', ...) throws a TypeError. unlockAchievement('constructor') returns false.
-
GameUIattaches handlers withaddEventListener. It uses no inline event attributes, so it works under ascript-srcwithout'unsafe-inline'. - Styles are set through
element.style, which astyle-srcpolicy does not restrict. The one exception is the XP bar, whose markup carriesstyle="width: 0%". Astyle-srcwithout'unsafe-inline'blocks that attribute and reports it. The bar still gets its width fromupdateXP. -
SoundManagerfetches registered audio URLs, which falls underconnect-src.
- The core has zero runtime dependencies, checked in CI.
- Releases are published from GitHub Actions with npm Trusted Publishing. No npm token exists. Each release carries a provenance attestation.
- Workflow actions are pinned to commit SHAs.
Start
Progression
Engine
Packages
Reference