Every delivery was refused as a signature mismatch, and nothing in the error
said why.
The provider signs one of two ways. A `whsec_` prefix means Standard Webhooks,
where the secret is a base64 key the verifier decodes; anything else is the
older scheme, where the secret is used as its own raw bytes. Which one a secret
belongs to is decided by when it was created, and every secret created now is
the new one.
The SDK's helper only implements the older scheme — it base64-encodes whatever
it is handed, so a Standard Webhooks secret becomes the literal bytes of the
string including its prefix, and every signature then fails against a key
derived quite differently.
The scheme is now read off the secret rather than configured, so rotating one
cannot put the two out of step. The verifier for the new scheme is the same
library the SDK uses underneath; nothing here hand-rolls crypto.
Tested with a real signature rather than only a rejection. A mismatch is easy to
assert by accident, and a test that only proved bad input is refused would have
passed against the broken version too.
Also teaches the product script to check shape and not just name: a one-time
product where a subscription is wanted cannot be subscribed to at all, and
reporting it as already-there hands back an id that fails at its first use.
Checkout, the customer portal, and the webhook that moves a team's plan.
Nothing money-shaped is stored. No price, no currency, no card detail — a
subscription's existence and its state are the whole of what crosses back,
because they are the only two facts the product needs and anything more would
be a second copy of a record somebody else is authoritative for.
Currency is deliberately not ours to hold. A product carries a price per
currency on their side and the customer's location picks one at checkout, so
there is no figure in this API that could drift from the one somebody is
charged. The team id travels as the customer's external id, which keeps the
mapping on their side rather than putting a foreign primary key in our schema.
Access follows their state, and the interesting cases are where that is not the
same as "paying right now". Cancelling keeps the plan: they paid to the end of
the period and turning them off when they click it takes something they bought.
A failed card keeps it too, because a retry that ends in payment should not
have cost them access in the middle. Only a revoked subscription takes it away,
which is the one moment nothing is left that was paid for. An event we do not
recognise changes nothing at all — new types are added by people who do not
know what we do with them, and a default that moved a plan would eventually
cancel an account nobody cancelled.
The webhook is the only route here no session protects, because its caller has
no account and never will. A signature over the raw body stands in for one, and
it is checked before the body is looked at — a body that has been parsed and
re-serialized is not the body that was signed. With no secret configured it
refuses everything rather than accepting anything, since otherwise knowing the
URL would be enough to set somebody's plan. Note also what is absent: no route
sets a plan, so there is no endpoint for granting yourself a subscription.
The product is written down as a definition with a script rather than clicked
into a dashboard, because the two environments are separate servers and nothing
made in one can be moved to the other. Promoting it is running the same script
with the other token, which is the only version of that which cannot drift. It
writes nothing without --apply and refuses to add a second product with a name
already taken.
Moving the issuer's state into Postgres removed the last thing that tied
either app to one hosting provider. What was left was a deployment tool
describing resources that no longer existed — so this replaces it with
`wrangler`, which is what actually deploys a Worker, and adds a second way
to run each app that involves no provider at all.
Each app now has a `wrangler.jsonc` with an environment per stage, and a
`Dockerfile` beside it. The handler is the same one in both cases; what
differs is only where its settings come from. Two of them gained a second
spelling so that nothing has to branch on the runtime: Postgres arrives as
a pooled binding or as `DATABASE_URL`, and the route to the issuer is a
service binding or `AUTH_INTERNAL_URL`.
That last one is new, and it is a split the binding was already making
without saying so. `AUTH_ISSUER_URL` has to be the issuer's public name,
because it is compared literally against every token's `iss` claim — but
the public name is often not routable from inside a deployment. So the
name and the route are two settings now rather than one that cannot be
both.
DNS moves out of code and into `docs/dns.md`, which lists every hostname
and what it is for. Six records that change roughly never did not need a
tool, and the table outlives whatever is answering the names — which is
the point, since some of them will stop being Workers. The sandbox
hostnames are hyphenated rather than nested for the same reason: a
certificate covering `*.nestri.io` covers one label and not two, so
`api-sandbox.nestri.io` can become an ordinary origin later without a
certificate having to be ordered for it first.
Also drops `EMAIL_DEV_LOG` from committed configuration into `.dev.vars`,
which `wrangler deploy` cannot upload. Printing a live sign-in code to a
log should not be one forgotten override away from production.
Squashes the current state of the internal working tree onto this history.
The two trees had grown apart with no common ancestor, so this is a content
sync rather than a merge, and the published history is preserved rather than
rewritten — a force-push here would break every existing fork and clone to no
benefit.
What lands:
- Waitlist: API route, core module, and migration 0006 alongside game aliases.
- User verification.
- CI, oxfmt config, editor settings.
- Assorted fixes across the API routes and core modules.
The repository's own README, the wordmark and the per-package READMEs are kept
from this side; the internal tree had dropped them and they are what a stranger
arriving here reads first.
The marketing site in the internal tree is deliberately not here. It is a
separate product with its own repo and its own licence, and this repo is the
open one — a closed component does not belong in it regardless of how convenient
the directory looked.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds a basic standalone "play site" that mimics current one in apps/www.
This is so self-hosters don't need to host whole site, but can just use
small version of it.
Yet to test so marking as draft, not at home currently so may take some
time. Also might be good idea to make Caddy-powered container out of
this later?
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
- New Features
- Introduces a standalone Play site with server output, accessible on
0.0.0.0:3000.
- Streams video via WebRTC into a canvas with continuous frame
rendering.
- Fullscreen and pointer lock support with optional keyboard lock for
navigation keys.
- Room-based routing with offline and loading states.
- Responsive 16:9 canvas and improved default layout styling.
- Chores
- Adds a multi-stage container build for efficient runtime images and a
lightweight init process.
- Includes configuration and project setup for the standalone package.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: DatCaptainHorse <datcaptainhorse@users.noreply.github.com>
## Description
<!-- Briefly describe the purpose and scope of your changes -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced a retry and dead-letter queue system for more robust event
processing.
- Added a retry handler for processing failed Lambda invocations with
exponential backoff.
- Enhanced event handling to support retry logic and improved error
management.
- **Refactor**
- Replaced SQS-based library event processing with an event bus-based
approach.
- Updated event names and structure for improved clarity and
consistency.
- Removed legacy library queue and related infrastructure.
- **Chores**
- Updated dependencies to include the AWS Lambda client.
- Cleaned up unused code and removed deprecated event handling logic.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
<!-- Briefly describe the purpose and scope of your changes -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added support for managing multiple Steam profiles per user, including
a new profiles page with avatar selection and profile management.
- Introduced a streamlined Steam authentication flow using a popup
window, replacing the previous QR code and team-based login.
- Added utilities for Steam image handling and metadata, including
avatar preloading and static Steam metadata mappings.
- Enhanced OpenID verification for Steam login.
- Added new image-related events and expanded event handling for Steam
account updates and image processing.
- **Improvements**
- Refactored the account structure from teams to profiles, updating
related UI, context, and storage.
- Updated API headers and authentication logic to use Steam IDs instead
of team IDs.
- Expanded game metadata with new fields for categories, franchises, and
social links.
- Improved library and category schemas for richer game and profile
data.
- Simplified and improved Steam API client methods for fetching user
info, friends, and game libraries using Steam Web API.
- Updated queue processing to handle individual game updates and publish
image events.
- Adjusted permissions and queue configurations for better message
handling and dead-letter queue support.
- Improved slug creation and rating estimation utilities.
- **Bug Fixes**
- Fixed avatar image loading to display higher quality images after
initial load.
- **Removals**
- Removed all team, member, and credential management functionality and
related database schemas.
- Eliminated the QR code-based login and related UI components.
- Deleted legacy team and member database tables and related code.
- Removed encryption utilities and deprecated secret keys in favor of
new secret management.
- **Chores**
- Updated dependencies and internal configuration for new features and
schema changes.
- Cleaned up unused code and updated database migrations for new data
structures.
- Adjusted import orders and removed unused imports across multiple
modules.
- Added new resource declarations and updated service link
configurations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
<!-- Briefly describe the purpose and scope of your changes -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced a new environment variable for improved configuration
options.
- **Chores**
- Updated and locked dependency versions for enhanced stability.
- Marked certain packages as private to prevent accidental publication.
- Updated package metadata and trusted dependencies for better
dependency management.
- **Refactor**
- Adjusted provider structure in the app to wrap children components
with an additional context provider.
- Simplified and cleaned up provider context code for maintainability.
- Improved import statements for clarity and type safety.
- **Style**
- Reorganized import order for consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
<!-- Briefly describe the purpose and scope of your changes -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added AWS queue infrastructure and SQS handler for processing Steam
game libraries and images.
- Introduced event-driven handling for new credentials and game
additions, including image uploads to S3.
- Added client functions to fetch Steam user libraries, friends lists,
app info, and related images.
- Added new database columns and schema updates to track game
acquisition, playtime, and family sharing.
- Added utility function for chunking arrays.
- Added new event notifications for library queue processing and game
creation.
- Added new lookup functions for categories and teams by slug.
- Introduced a new Team API with endpoints to list and fetch teams by
slug.
- Added a new Steam library page displaying game images.
- **Enhancements**
- Improved game creation with event notifications and upsert logic.
- Enhanced category and team retrieval with new lookup functions.
- Renamed and refined image categories for clearer classification.
- Expanded dependencies for image processing and AWS SDK integration.
- Improved image processing utilities with caching, ranking, and
metadata extraction.
- Refined Steam client utilities for concurrency and error handling.
- **Bug Fixes**
- Fixed event publishing timing and removed deprecated credential
retrieval methods.
- **Chores**
- Updated infrastructure configurations with increased timeouts, memory,
and resource linking.
- Added new dependencies for image processing, caching, and AWS SDK
clients.
- Refined internal code structure and imports for clarity.
- Removed Steam provider and related UI components from the frontend.
- Disabled authentication providers and Steam-related routes in the
frontend.
- Updated API fetch handler to accept environment bindings.
- **Refactor**
- Simplified query result handling and renamed functions for better
clarity.
- Removed outdated event handler in favor of consolidated event
subscriber.
- Consolidated and simplified database relationships and permission
queries.
- **Tests**
- No explicit test changes included in this release.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
<!-- Briefly describe the purpose and scope of your changes -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Expanded data model to include users, Steam accounts, teams, members,
and friends lists for richer user and team management.
- Introduced detailed relationships and row-level permissions for
enhanced access control.
- **Chores**
- Updated dependency version for improved compatibility.
- Adjusted environment variables and configuration for improved
performance and reliability.
- Updated development scripts for clearer SQL permissions generation and
workflow separation.
- Enhanced .gitignore to exclude SQL files from version control.
- **Refactor**
- Restructured schema and permissions logic for greater flexibility and
security.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
<!-- Briefly describe the purpose and scope of your changes -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced a real-time Steam login flow using QR codes and server-sent
events (SSE) for team creation and authentication.
- Added Steam account and friend management, including secure credential
storage and friend list synchronization.
- Integrated Steam login endpoints into the API, enabling QR code-based
login and automated team setup.
- **Improvements**
- Enhanced data security by implementing encrypted storage for sensitive
tokens.
- Updated database schema to support Steam accounts, teams, memberships,
and social connections.
- Refined type definitions and consolidated account-related information
for improved consistency.
- **Bug Fixes**
- Fixed trade ban status representation for Steam accounts.
- **Chores**
- Removed legacy C# Steam authentication service and related
configuration files.
- Updated and cleaned up package dependencies and development tooling.
- Streamlined type declaration files and resource definitions.
- **Style**
- Redesigned the team creation page UI with a modern, animated QR code
login interface.
- **Documentation**
- Updated OpenAPI documentation for new Steam login endpoints.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
<!-- Briefly describe the purpose and scope of your changes -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Centralized and standardized error response schemas for APIs.
- Utility functions for result formatting and enhanced validation error
handling.
- New utility modules for authentication and OAuth provider handling.
- Added Discord OAuth user data fetching with email verification.
- **Bug Fixes**
- Improved error safety in cloud task creation by preventing potential
runtime errors.
- **Refactor**
- Major simplification and reorganization of API routes and
authentication logic.
- Migration from valibot to zod for schema validation.
- Streamlined import paths and consolidated utility exports.
- Simplified TypeScript and .gitignore configuration for easier
maintenance.
- Disabled machine authentication provider and related logic.
- **Chores**
- Removal of unused or deprecated API endpoints, database migration, and
permissions deployment code.
- Updated package dependencies and scripts for improved reliability and
performance.
- Enhanced documentation and updated project metadata.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
This attempts to connect the Steam account to user account... for easier
management
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Enhanced user profiles and account views now display integrated Steam
account details and enriched team associations for a more comprehensive
experience.
- **Chores**
- Backend and database refinements have been implemented to improve
system stability, data integrity, and overall performance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
<!-- Briefly describe the purpose and scope of your changes -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Upgraded API and authentication services with dynamic scaling,
enhanced load balancing, and real-time interaction endpoints.
- Introduced new commands to streamline local development and container
builds.
- Added new endpoints for retrieving Steam account information and
managing connections.
- Implemented a QR code authentication interface for Steam, enhancing
user login experiences.
- **Database Updates**
- Rolled out comprehensive schema migrations that improve data integrity
and indexing.
- Introduced new tables for managing Steam user credentials and machine
information.
- **UI Enhancements**
- Added refreshed animated assets and an improved QR code login flow for
a more engaging experience.
- Introduced new styled components for displaying friends and games.
- **Maintenance**
- Completed extensive refactoring and configuration updates to optimize
performance and development workflows.
- Updated logging configurations and improved error handling mechanisms.
- Streamlined resource definitions in the configuration files.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
## Description
This fixes an issue where `openauthjs` throws timeout errors while
attempting to access DynamoDB
> I am so glad this was not a major issue 😅
## Related Issues
[OpenAuth Error TypeError: fetch failed while accessing DynamoDB on AWS
#5543
](https://github.com/sst/sst/issues/5543)
[Error TypeError: fetch failed while accessing DynamoDB on AWS
#220](https://github.com/toolbeam/openauth/issues/220)
## Type of Change
- [x] Bug fix (non-breaking change)
- [ ] New feature (non-breaking change)
- [ ] Breaking change (fix or feature that changes existing
functionality)
- [ ] Documentation update
- [ ] Other (please describe):
## Checklist
- [x] I have updated relevant documentation
- [ ] My code follows the project's coding style
- [ ] My changes generate no new warnings/errors
## Screenshots/Demo

## Description
<!-- Briefly describe the purpose and scope of your changes -->
## Related Issues
<!-- List any related issues (e.g., "Closes #123", "Fixes #456") -->
## Type of Change
- [x] Bug fix (non-breaking change)
- [ ] New feature (non-breaking change)
- [ ] Breaking change (fix or feature that changes existing
functionality)
- [ ] Documentation update
- [ ] Other (please describe):
## Checklist
- [ ] I have updated relevant documentation
- [ ] My code follows the project's coding style
- [ ] My changes generate no new warnings/errors
## Notes for Reviewers
<!-- Point out areas you'd like reviewers to focus on, questions you
have, or decisions that need discussion -->
## Screenshots/Demo
<!-- If applicable, add screenshots or a GIF demo of your changes
(especially for UI changes) -->
## Additional Context
<!-- Add any other context about the pull request here -->