Engineering MyZubster: Verifiable Crypto Settlements, Refresh-Token Rotation, Revocable Sessions, and Cross-Mongoose Runtime Hardening
MyZubster recently completed a substantial infrastructure iteration spanning two systems that initially appear unrelated: contributor bounty settlement and authentication/session security.
They share an important engineering requirement:
external or client-side state must not be treated as authoritative without server-side verification and persistence.
For bounty payments, a blockchain transaction needs to become a verified, replay-safe treasury record.
For authentication, possession of a cryptographically valid JWT should not permanently imply that a session is still authorized.
This development cycle introduced infrastructure addressing both problems.
This article goes through the implementation, security properties, failure modes we discovered during integration testing, and the validation performed before pushing the final changes.
1. The Systems We Changed
The work covered two major areas.
Treasury and bounty settlement
We implemented infrastructure for recording verified cryptocurrency conversions associated with bounty settlement.
The flow now supports:
external transaction
│
▼
blockchain reference
│
▼
conversion verification
│
▼
normalized treasury object
│
▼
dry-run validation
│
▼
idempotency check
│
▼
persistent settlement record
Authentication and account security
MYZ-71 introduced a more substantial authentication lifecycle:
authentication
│
▼
persistent server session
│
├── short-lived access token
│
└── rotating opaque refresh token
│
▼
replay detection
│
▼
session revocation
The frontend then gained automatic renewal, account/device controls, terminal-expiry recovery, and CSRF protection for cookie-authenticated mutations.
Part I — Verifiable Cryptocurrency Bounty Settlement
2. Moving Beyond “A Transaction Was Sent”
Sending cryptocurrency is only one part of a bounty system.
From an engineering perspective, the application needs to answer several additional questions:
- Why was the transaction made?
- Which asset left the treasury?
- Which asset arrived?
- Which network was used?
- What external provider participated?
- Which blockchain transaction proves the operation?
- Has the conversion been independently verified?
- Has this exact operation already been recorded?
- Can the dashboard consume the result without directly coupling itself to persistence?
For the settlement flow implemented during this cycle, the normalized record contains information such as:
{
"purpose": "BOUNTY_SETTLEMENT",
"provider": "SimpleSwap",
"source": {
"asset": "BTC",
"amount": "0.000464",
"txId": "2ea0bc209a2d5bcfbf520f830f1a39dee0691e47c461afc316e5aeb2e83cdd2d"
},
"target": {
"asset": "ETH",
"network": "ethereum-mainnet",
"amount": "0.014355678390291923",
"txId": "0x62b58e69931ef6046d8f68df39c118fe0b1fc7234b88c780d26a8b53fdcddcc6"
},
"state": "CONVERSION_COMPLETED",
"verification": {
"status": "VERIFIED"
}
}
This represents the BTC → ETH treasury conversion as application state rather than leaving the operation as an external exchange receipt or manually interpreted transaction history.
3. Separating Verification From Persistence
A financial script should not immediately mutate production data simply because it successfully parsed its input.
We therefore implemented a dry-run path.
The sequence becomes:
construct record
│
▼
validate input
│
▼
verify external reference
│
▼
print normalized result
│
▼
STOP
The operator sees:
DRY-RUN OK — no database write performed
Only explicit commit mode proceeds to persistence.
This creates a useful operational boundary:
verification != mutation
That distinction matters for treasury operations because malformed metadata can be caught before it becomes part of the persistent accounting history.
4. Idempotent Conversion Recording
Financial scripts are frequently rerun.
A terminal disconnect, uncertain command result, deployment retry, or operator mistake should not produce a second logical settlement record.
The first committed execution recorded the conversion:
RECORDED
{
"id": "6ab96bcb4c201256912e837a",
"purpose": "BOUNTY_SETTLEMENT",
"state": "CONVERSION_COMPLETED",
"verificationStatus": "VERIFIED"
}
Repeating the operation returned:
IDEMPOTENT REPLAY — conversion already recorded
instead of creating a duplicate.
The desired invariant is:
same external conversion
+
same transaction identity
=
same internal logical record
This is much safer than relying on the operator to remember whether a previous command completed.
5. Provider Boundary for Settlement Observability
The settlement dashboard should not need to understand database internals.
We introduced a conversion-provider boundary so the dashboard can receive preloaded conversion information.
Conceptually:
buildDashboard({
conversionProvider: () => conversion
});
This provides two useful properties.
First, the dashboard can consume treasury state without performing hidden database I/O.
Second, provider failure does not need to crash the entire dashboard.
If the repository fails, the conversion layer can instead return:
configured: false
items: []
reason: conversion repository unavailable
and emit an explicit warning.
That is deliberate degraded behavior.
For operational dashboards, an unavailable subsystem should be visible as unavailable — not silently represented as empty valid state and not allowed to crash unrelated observability.
Part II — Revocable Authentication Sessions
6. Why JWT Validation Alone Was Not Enough
A signed JWT answers an important question:
Was this token issued by a trusted signer and has its cryptographic validity expired?
It does not necessarily answer:
Does the server still want this browser session to exist?
Those are different questions.
A user may need to revoke a stolen device.
A refresh token may have been replayed.
An administrator or security flow may invalidate a session.
A user may explicitly log out.
For these cases, authentication needs authoritative server-side state.
We introduced persistent AuthSession records.
The resulting model is conceptually:
User
│
├── AuthSession A
│ ├── sessionId
│ ├── expiry
│ ├── device metadata
│ ├── lastSeenAt
│ ├── refreshTokenHash
│ └── revocation state
│
├── AuthSession B
│
└── AuthSession C
Access JWTs contain a session identifier.
JWT verification can therefore be followed by server-session validation.
A valid signature no longer necessarily means an active session.
7. Refresh Tokens Became Opaque, Persistent, and Rotating
The new refresh credential is an opaque token.
Its raw value is not persisted.
Instead, the server stores an HMAC-SHA256 representation.
The lifecycle looks like this:
refresh token R1
│
▼
hash / identify
│
▼
validate session
│
▼
atomically consume R1
│
▼
issue R2
│
▼
store hash(R2)
R1 is now consumed.
The server maintains bounded history for previously consumed refresh-token hashes.
The bounded part matters: security metadata must not create an indefinitely growing session document.
8. Atomic Rotation
Refresh rotation introduces a concurrency problem.
Imagine two requests attempting to use R1 at nearly the same time:
Request A ── R1 ──┐
├── session
Request B ── R1 ──┘
A naive implementation could allow both requests to observe R1 as valid before either update becomes visible.
Rotation therefore needs an atomic state transition.
Conceptually:
UPDATE AuthSession
WHERE
session = S
AND currentRefreshHash = hash(R1)
SET
currentRefreshHash = hash(R2)
consumed += hash(R1)
Only the request that successfully matches the expected current state should rotate the token.
This is effectively compare-and-swap behavior applied to authentication state.
9. Refresh Replay Detection
Single-use refresh tokens provide another security signal.
If R1 was already consumed and later appears again, something unusual happened.
Possibilities include:
- credential theft;
- duplicated stale browser state;
- client bugs;
- copied authentication material;
- an actual replay attempt.
Our implementation treats reuse as a security event.
The tested behavior is:
consumed refresh token reused
│
▼
AUTH_REFRESH_REPLAY
│
▼
revoke complete session
│
▼
revokedReason = refresh-token-replay
The response is therefore stronger than simply rejecting the stale token.
The associated session itself becomes invalid.
10. Frontend Refresh Deduplication
Server-side single-use credentials require corresponding client-side concurrency control.
Suppose a page launches five API requests and the access token expires.
All five may receive 401.
Without coordination:
401 A → refresh
401 B → refresh
401 C → refresh
401 D → refresh
401 E → refresh
Only one of those refresh attempts can legitimately consume the current refresh token.
So the browser authentication client shares an in-flight refresh promise:
401 A ─┐
401 B ─┤
401 C ─┼──► one refresh operation
401 D ─┤
401 E ─┘
│
▼
new access state
│
▼
retry requests
This aligns frontend concurrency semantics with backend single-use token semantics.
Requests are retried only once.
The client does not enter an infinite 401 → refresh → retry loop.
Part III — Account Security
11. Session Management API
The session architecture is exposed through account-security endpoints:
POST /api/auth/refresh
POST /api/auth/logout
GET /api/auth/me
GET /api/auth/me/sessions
DELETE /api/auth/me/sessions/:sessionId
These endpoints provide the foundation for user-controlled session management.
12. Active Device Management
The frontend now contains an account-security surface.
Users can inspect session information including:
- whether the session is the current one;
- creation time;
- last activity;
- expiry;
- available revocation actions.
A remote session can be revoked without destroying every other login.
The current session can also be terminated.
When that happens, server-side state is revoked and browser authentication state is cleared.
This turns logout from a mostly client-side token deletion into an actual server-side authorization transition.
Session observability is useful, but it should not require retaining unnecessary sensitive network data.
The session implementation therefore does not store raw client IP addresses as plain values.
Instead, IP information can be represented through an HMAC-SHA256 digest.
This allows certain correlation/security use cases without turning the session collection into a direct historical database of raw IP addresses.
Session lifetime is also bounded.
14. A Renewable Authenticated Fetch Layer
The Metaverse API was moved onto a reusable authenticated request layer.
The high-level flow is:
API request
│
▼
access accepted?
┌──┴──┐
yes no
│ │
return ▼
renewable auth failure?
│
┌──┴──┐
no yes
│ │
fail ▼
refresh
│
▼
retry once
Not every 401 is renewable.
An explicitly revoked session, for example, should not cause endless attempts to resurrect authentication.
The client distinguishes terminal authentication state from renewable access-token failure.
15. Terminal Expiry Events
If refresh fails terminally, the browser:
- clears migration authentication state;
- emits an authentication-expired event;
- redirects through the login flow.
This behavior was connected to:
- Neon Plaza;
- Metaverse room pages;
- room creation.
Multiple concurrent failures are deduplicated so the application does not perform several competing redirects.
16. Preserving the Intended Destination
Authentication expiry should not destroy user navigation context.
The system preserves a local return path so a user can authenticate and return to the intended Metaverse location.
That can include:
/metaverse/rooms/example?invite=...#section
But return paths are also security-sensitive.
Protocol-relative destinations are rejected.
The application falls back to a known local Metaverse path when the return target is unsafe.
This prevents the convenience mechanism from becoming an open-redirect primitive.
Part V — CSRF Protection
17. Cookies Changed the Threat Model
Once authentication relies on HttpOnly cookies, the browser automatically attaches those credentials to matching requests.
That is useful for protecting credentials from direct JavaScript access, but it also means CSRF must be addressed explicitly.
The server now distinguishes:
Authorization: Bearer ...
from ambient cookie authentication.
Unsafe cookie-authenticated browser mutations require trusted request-origin information.
For applicable unsafe methods, the server evaluates browser request context.
Cross-site Fetch Metadata can be rejected before session lookup:
Sec-Fetch-Site: cross-site
│
▼
reject
Trusted Origin or Referer information is checked for cookie-authenticated mutations.
Rejected requests return a structured error:
AUTH_CSRF_REJECTED
Trusted production origins can be configured rather than hardcoded.
Bearer clients remain supported during the migration because explicit bearer credentials have different ambient-credential behavior from browser cookies.
Part VI — Structured Authentication Errors
19. Error Codes Instead of Raw Cryptographic Errors
Raw JWT/library exceptions are not a good public API.
The authentication layer now uses structured application errors and request IDs.
Conceptually:
{
"error": {
"code": "AUTH_...",
"request_id": "..."
}
}
This creates a stable contract between server and frontend.
The UI can distinguish:
- access expiry;
- revoked sessions;
- refresh replay;
- terminal refresh failure;
- CSRF rejection;
without parsing arbitrary exception strings.
Request IDs also improve operational debugging.
Part VII — The Mongoose/BSON Failure We Found During Testing
20. The Initial Symptom
One of the most useful results of the final integration test was not a passing test.
It was a hang.
The social-identity suite stopped at:
RUNS tests/socialIdentityService.test.js
Eventually it failed with:
MongooseError:
Operation `metaversecharacters.findOne()` buffering timed out after 10000ms
The same thing happened during test cleanup:
metaversecharacters.deleteMany()
buffering timed out
At first glance, this looked like a MongoMemoryServer or asynchronous-test problem.
It wasn't.
21. Two Mongoose Runtimes in One Process
The root application used:
Mongoose 7.8.12
while the nested backend used:
Mongoose 8.24.3
User and AuthSession came from the root runtime.
MetaverseCharacter came from:
backend/src/models/MetaverseCharacter
and that model resolved its own:
require('mongoose')
against the backend installation.
So the test had effectively created:
MongoMemoryServer
│
▼
root Mongoose 7
│
├── User
└── AuthSession
backend Mongoose 8
│
└── MetaverseCharacter
X
no connected test DB
The timeout suddenly made sense.
22. Connecting Both Runtimes Revealed the Deeper Problem
As a diagnostic step, both Mongoose instances were connected to the same in-memory MongoDB.
The timeout disappeared.
But the next error was more informative:
BSONVersionError:
Unsupported BSON version,
bson types must be from bson 6.x.x
An ObjectId produced by one Mongoose/BSON ecosystem was being passed into a model using another BSON implementation.
So simply connecting both instances was not a sound fix.
It exposed the deeper boundary problem.
23. Model Factory as the Boundary Repair
We did not solve this by increasing Jest timeouts.
We did not keep --forceExit.
We did not normalize every ObjectId manually and hope no other BSON type crossed the boundary.
Instead, MetaverseCharacter was changed to expose a model factory.
Conceptually:
function createMetaverseCharacterModel(mongoose) {
const schema = new mongoose.Schema({
// ...
});
return mongoose.models.MetaverseCharacter ||
mongoose.model('MetaverseCharacter', schema);
}
Backend consumers can continue using the backend Mongoose runtime.
Root consumers can instantiate the same schema using the root runtime.
That changes the topology to:
Root application
│
▼
root Mongoose
│
├── User
├── AuthSession
└── MetaverseCharacter
and:
Backend application
│
▼
backend Mongoose
│
└── MetaverseCharacter
The schema definition can be shared without forcing two incompatible Mongoose runtime objects into the same database operation.
24. Why This Matters Beyond Tests
It would have been easy to classify the failure as “just a Jest problem.”
That would have been incorrect.
The test exposed an actual architectural boundary:
shared model source
≠
shared Mongoose runtime
Node's module resolution can load different versions of the same dependency from different package trees.
ODM objects such as ObjectIds, models, connections, and schemas are not automatically interchangeable simply because they ultimately represent MongoDB concepts.
The lesson is broader:
When a Node.js process contains multiple ODM/library runtimes, pass primitives or explicitly bind shared schemas to the owning runtime. Do not assume runtime-specific objects are portable across package boundaries.
Part VIII — Repairing Source Corruption
25. UTF-8 and Control-Character Validation
During the MYZ-71 repair we also discovered corrupted frontend source content.
The affected surfaces included authentication/security and Metaverse pages.
We explicitly checked for:
- Unicode replacement characters;
- unexpected control characters;
- malformed JSX;
- corrupted localized strings.
The affected source was repaired and then checked again before running the frontend suite.
This was important because some apparent React/parser failures were not behavioral regressions at all — they were malformed source bytes or broken string literals.
26. JavaScript String Parsing Failure
Another backend gate exposed a malformed JavaScript string containing an apostrophe:
Autorizzazione GitHub non associata all'account ...
The single quote terminated the surrounding single-quoted JavaScript string.
This prevented Babel/Jest from parsing the controller.
The string was repaired and syntax validation was performed before rerunning the backend suites.
This is a simple bug, but it reinforces why syntax/build gates belong in the final validation pipeline even after behavioral tests have been added.
Part IX — Validation
27. Backend Final Gate
After repairing the Mongoose boundary and JavaScript syntax, the targeted backend gate completed successfully:
Test Suites: 3 passed, 3 total
Tests: 18 passed, 18 total
Time: 4.478 s
The suites covered the relevant session controller, social authentication callback, and social identity behavior.
The previously hanging social identity tests now completed normally.
28. Frontend Final Gate
The targeted frontend gate also completed successfully:
Test Suites: 4 passed, 4 total
Tests: 13 passed, 13 total
Coverage included the authentication-expiry redirect, account-security page, auth-session API, and Metaverse API behavior.
29. Production Build
We then generated an optimized React production build:
Creating an optimized production build...
Compiled with warnings.
The build completed successfully.
The remaining ESLint warnings were non-blocking and outside the scope of the repair.
They were deliberately not mixed into the security fix simply to produce an artificially warning-free diff.
30. Git Integrity Gate
Before committing:
git diff --cached --check
completed cleanly.
Generated build artifacts were removed from the commit.
An unrelated untracked directory was also deliberately kept outside the MYZ-71 commit.
The final repair was committed as:
1878e02a
fix: harden revocable account sessions
and pushed to the MYZ-71 branch.
Part X — What Is Operational Now
31. Treasury
The implemented treasury infrastructure now supports:
bounty settlement purpose
│
▼
crypto source transaction
│
▼
asset conversion
│
▼
target-chain transaction
│
▼
verification
│
▼
dry-run
│
▼
idempotent persistence
│
▼
dashboard provider
The recorded BTC → ETH operation reached:
CONVERSION_COMPLETED
VERIFIED
and replaying the recorder did not create a duplicate conversion.
32. Authentication
The implemented authentication/session infrastructure now provides:
login
│
▼
persistent AuthSession
│
├── access JWT bound to session
│
└── opaque rotating refresh credential
│
├── atomic rotation
├── bounded consumed-token history
└── replay detection
│
▼
session revocation
The frontend adds:
authenticated request
│
▼
renew if allowed
│
▼
retry once
│
▼
terminal failure?
│
▼
clear state + auth-expired event
│
▼
login
│
▼
restore safe local destination
Part XI — Security Properties Achieved
The resulting implementation has several concrete security properties.
Server authority over sessions
A cryptographically valid JWT can still be rejected when its server session has been revoked or removed.
Single-use refresh credentials
Refresh credentials rotate instead of remaining indefinitely reusable.
Replay detection
Reuse of consumed refresh state causes session revocation.
No raw refresh-token persistence
Refresh credentials are represented server-side through cryptographic hashes.
Client/server concurrency alignment
The frontend shares concurrent refresh work while the backend performs atomic token rotation.
Remote session revocation
A user can invalidate another authenticated device without necessarily destroying every active session.
Cookie mutation protection
Unsafe cookie-authenticated browser operations are protected by trusted-origin/Fetch Metadata checks.
Structured auth failures
Clients receive stable authentication semantics rather than raw JWT/library errors.
Safe return navigation
Authentication recovery preserves useful local navigation without accepting arbitrary protocol-relative redirect destinations.
Explicit ODM runtime ownership
The same Metaverse schema can be bound to the Mongoose runtime that actually owns the surrounding connection and models.
Replay-safe treasury persistence
Reexecuting the same verified conversion recorder does not produce duplicate settlement state.
Part XII — What We Deliberately Did Not Claim
Engineering reports are more useful when they clearly distinguish completed infrastructure from future work.
This iteration does not mean the entire MYZ-71 roadmap is finished.
Remaining work includes:
- passkeys and/or magic-link authentication;
- step-up authentication for sensitive operations;
- extending automatic renewal to authenticated clients outside the current Metaverse integration;
- completing migration away from legacy localStorage/bearer compatibility;
- strict production server-session enforcement after the migration window;
- production trusted-origin verification;
- broader OAuth production verification;
- production MongoDB stability validation.
On the treasury side, a verified conversion record is also not the final form of a contributor payment platform.
Future settlement work can connect:
bounty
↓
contributor
↓
approved amount
↓
payment instruction
↓
source transaction
↓
optional conversion
↓
destination transaction
↓
verification
↓
notification
↓
settled bounty state
into one auditable lifecycle.
Conclusion
The most valuable part of this development cycle was not the number of endpoints or React components added.
It was the strengthening of system boundaries.
For payments:
blockchain activity
↓
verified application state
↓
idempotent treasury record
For authentication:
client credential
↓
server-authoritative session
↓
rotating credentials
↓
replay detection
↓
revocation
And for the Node/MongoDB architecture:
shared schema
↓
explicit runtime ownership
↓
consistent Mongoose connection
The final repair was validated with 18/18 targeted backend tests, 13/13 targeted frontend tests, a successful optimized frontend build, and a clean Git diff check.
More importantly, integration testing exposed a real Mongoose 7/Mongoose 8 BSON boundary that would have been easy to hide with larger timeouts. Fixing the ownership boundary instead of suppressing the symptom left the architecture in a better state.
MyZubster now has stronger primitives for two areas where correctness matters disproportionately: moving value and maintaining identity.
That gives us a much safer base for the next layer of automation.