Skip to content

✨ server: support factory selection in credential creation - #1089

Merged
cruzdanilo merged 2 commits into
mainfrom
factory-selection
Jun 12, 2026
Merged

✨ server: support factory selection in credential creation#1089
cruzdanilo merged 2 commits into
mainfrom
factory-selection

Conversation

@nfmelendez

@nfmelendez nfmelendez commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added factory selection support during credential creation and authentication flows. Users can now optionally specify a factory address when registering or authenticating with credentials. Factory selections are validated against a whitelist of supported factories to ensure security and compatibility.
  • Tests

    • Enhanced test coverage for factory selection in authentication and registration workflows.

@nfmelendez
nfmelendez requested a review from cruzdanilo as a code owner June 11, 2026 19:15
@changeset-bot

changeset-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c4a808f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@exactly/server Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This PR adds optional factory parameter support to the credential creation system. It introduces a whitelist of valid factories computed via CREATE3 address derivation, updates createCredential to accept and use an optional factory, and routes the factory parameter through authentication and registration endpoints with validation.

Changes

Factory Selection Support

Layer / File(s) Summary
Factory Whitelist Infrastructure
server/utils/validFactories.ts
Exports validFactories set of valid Ethereum addresses derived from CREATE3 scheme, supporting Optimism Sepolia and Base Sepolia chains with a fallback mechanism. Includes deriveCreate3 helper for address derivation using ABI packing and keccak hashing.
Credential Creation with Optional Factory
server/utils/createCredential.ts
createCredential now accepts optional factory in options, defaults to exaAccountFactoryAddress, uses it for account derivation, stores it in the credential record, and returns it alongside credentialId, x, y, and auth.
Authentication Endpoint Factory Support
server/api/auth/authentication.ts
POST / endpoint accepts optional factory query parameter, validates against validFactories, routes it to createCredential for SIWE-based credential creation, and enforces factory match for non-SIWE verification paths.
Registration Endpoint Factory Support
server/api/auth/registration.ts
POST / endpoint accepts optional factory query parameter with whitelist validation, extracts and validates it in the handler, and passes it to createCredential alongside existing webauthn and source parameters.
Test Coverage and Assertion Modernization
server/test/api/auth.test.ts
Adds new authentication tests validating factory parameter handling: creating credentials with non-default factories, rejecting invalid factories with bad factory, and enforcing factory match during subsequent WebAuthn authentication. Modernizes Redis session consumption assertions across tests to use async-aware await expect(...).resolves.toBe(0) syntax.
Release Notes
.changeset/brave-foxes-beam.md
Patch release for @exactly/server documenting factory selection support during credential creation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • exactly/exa#621: Modifies auth tests to change how account factory addresses are supplied via injection and valid factories, aligning test setup with factory-selection logic.
  • exactly/exa#674: Extends credential creation options by adding optional source from Client-Fid alongside modifications to createCredential, similar to this PR's factory parameter addition.

Suggested reviewers

  • cruzdanilo
  • dieguezguille
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding support for factory selection during credential creation across authentication and registration flows.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch factory-selection
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch factory-selection

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for factory selection during credential creation and authentication. It adds validation for the factory query parameter, updates credential creation logic to handle the selected factory, and includes a utility to derive valid factories. The review feedback highlights a potential issue where legacy credentials with a null or undefined factory field in the database could cause a validation error when parsed. To prevent this, the reviewer suggests falling back to exaAccountFactoryAddress and importing it in authentication.ts.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread server/api/auth/authentication.ts
Comment thread server/api/auth/authentication.ts
@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
1055 1 1054 1
View the top 1 failed test(s) by shortest run time
test/e2e.ts > e2e > runs server
Stack Traces | 326s run time
No failure message available
View the full list of 1 ❄️ flaky test(s)
local::local

Flake rate in main: 86.21% (Passed 4 times, Failed 25 times)

Stack Traces | 308s run time
Assertion is false: "\$[\s\d,.\xa0]+, AVAILABLE BALANCE" is visible

@nfmelendez

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: c4a808f03c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
server/utils/createCredential.ts (1)

27-45: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Validate factory at the persistence boundary.

createCredential now derives the account from options.factory and stores that value in credentials.factory, but the whitelist check only exists in server/api/auth/authentication.ts and server/api/auth/registration.ts. Any other caller of this utility can bypass the whitelist and persist an unsupported factory. Guard it here too, and keep the route-level checks only as early request validation.

♻️ Proposed fix
 import { exaAccountFactoryAddress } from "`@exactly/common/generated/chain`";
 import { Address } from "`@exactly/common/validation`";
 
 import { updateWebhookAddresses } from "./alchemy";
 import authSecret from "./authSecret";
 import decodePublicKey from "./decodePublicKey";
 import { customer } from "./sardine";
 import { identify } from "./segment";
+import validFactories from "./validFactories";
 import database from "../database";
 import { credentials } from "../database/schema";
 import { webhookId } from "../hooks/activity";
@@
 ) {
   const factory = options?.factory ?? exaAccountFactoryAddress;
+  if (!validFactories.has(factory)) throw new Error("bad factory");
   const publicKey =
     options?.webauthn?.publicKey ?? (isAddress(credentialId) ? new Uint8Array(hexToBytes(credentialId)) : undefined);

As per coding guidelines, "extract and abstract only with reuse (two or more uses) or foot-gun encapsulation."

Source: Coding guidelines

server/test/api/auth.test.ts (1)

463-658: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Registration's new factory path still has no coverage.

server/api/auth/registration.ts now parses, whitelists, and persists query.factory, but the registration suite never sends a factory query on either the success or rejection path. Add one non-default factory registration case and one invalid-factory case that assert the stored credentials.factory, so auth and registration stay aligned.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4ccc70bd-8079-4cf3-99b8-c0ce8f5c6663

📥 Commits

Reviewing files that changed from the base of the PR and between df0fd6c and c4a808f.

📒 Files selected for processing (6)
  • .changeset/brave-foxes-beam.md
  • server/api/auth/authentication.ts
  • server/api/auth/registration.ts
  • server/test/api/auth.test.ts
  • server/utils/createCredential.ts
  • server/utils/validFactories.ts

Comment thread server/test/api/auth.test.ts
@cruzdanilo
cruzdanilo merged commit c4a808f into main Jun 12, 2026
11 of 12 checks passed
@cruzdanilo
cruzdanilo deleted the factory-selection branch June 12, 2026 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants