diff --git a/.changeset/dts-relative-paths.md b/.changeset/dts-relative-paths.md index 1669c8f..1900fd7 100644 --- a/.changeset/dts-relative-paths.md +++ b/.changeset/dts-relative-paths.md @@ -1,5 +1,5 @@ --- -"@seamless-auth/react": patch +'@seamless-auth/react': patch --- Emit relative import paths in the published type declarations. The build kept the diff --git a/AGENTS.md b/AGENTS.md index 7290e54..bc83211 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -113,17 +113,25 @@ Runtime exports currently include: - `usePasskeySupport` - `hasScopedRole` and `roleGrantsAccess` - `encodePrfSalt`, `extractPasskeyPrfResult`, and `isPasskeyPrfSupported` +- `SeamlessAuthError` + +Every request method on the client and the provider resolves to a +`SeamlessAuthResult` (`{ data, error }`) and does not throw for HTTP or +transport failures. `isPasskeyPrfSupported` is the exception (a local capability +check returning a boolean). Exported types currently include the provider/client input and result types plus domain models, for example: - `AuthContextType`, `Credential`, `User`, `Organization`, `OrganizationMembership` +- `SeamlessAuthResult`, `MessageResult` - `LoginInput`, `LoginMethod`, `LoginStartResult`, `RegisterInput`, `CurrentUserResult` -- `PasskeyMetadata`, `PasskeyLoginResult`, `PasskeyLoginWithPrfResult`, `PasskeyRegistrationResult`, `RegisterPasskeyOptions` +- `PasskeyMetadata`, `PasskeyLoginData`, `PasskeyRegistrationData`, `RegisterPasskeyOptions` - `PasskeyPrfInput`, `PasskeyPrfResult` +- Credential types: `CredentialUpdateResult` - OAuth types: `OAuthProvider`, `OAuthProvidersResult`, `StartOAuthLoginInput`, `StartOAuthLoginResult`, `FinishOAuthLoginInput` -- Organization types: `CreateOrganizationInput`, `UpdateOrganizationInput`, `OrganizationMemberInput`, `OrganizationMemberUpdateInput`, `OrganizationsResult`, `OrganizationResult`, `OrganizationMembersResult` -- Step-up types: `StepUpMethod`, `StepUpStatus`, `StepUpVerificationResult`, `StepUpWithPasskeyPrfResult` +- Organization types: `CreateOrganizationInput`, `UpdateOrganizationInput`, `OrganizationMemberInput`, `OrganizationMemberUpdateInput`, `OrganizationsResult`, `OrganizationResult`, `OrganizationMembersResult`, `OrganizationMembershipResult`, `OrganizationSwitchResult` +- Step-up types: `StepUpMethod`, `StepUpStatus`, `StepUpPrfData` - `SeamlessAuthClient` and `SeamlessAuthClientOptions` Public API changes should be treated deliberately: @@ -178,9 +186,9 @@ The built-in flows and exported client assume these route families exist: - `/webAuthn/login/finish` - `/webAuthn/register/start` - `/webAuthn/register/finish` -- `/otp/generate-phone-otp`, `/otp/generate-email-otp`, and their `-login-` variants +- `POST /otp/generate-phone-otp`, `/otp/generate-email-otp`, and their `-login-` variants - `/otp/verify-phone-otp`, `/otp/verify-email-otp`, and their `-login-` variants -- `/magic-link` +- `POST /magic-link` - `/magic-link/check` - `/magic-link/verify/:token` - `/oauth/providers`, `/oauth/:providerId/start`, `/oauth/:providerId/callback` @@ -195,6 +203,12 @@ The `@seamless-auth/express` adapter mounts the WebAuthn routes as `/webAuthn` Keep the client paths byte-for-byte aligned with the adapter's mounted paths; do not "normalize" casing here in isolation. +The OTP generate routes and `/magic-link` are `POST`, not `GET`. As `GET` they +were state-changing simple cross-site requests (an `` tag could trigger SMS +or email sends), so both the client and the adapter serve them over `POST` with a +JSON body to force a CORS preflight. This depends on a matching adapter version; +do not revert them to `GET` in isolation. + Before documenting new flow behavior, verify the route contract in `seamless-auth-server` or `seamless-auth-api`. ## Migration Status @@ -234,8 +248,7 @@ For docs work: The biggest remaining gaps are no longer hidden internals. They are mostly polish and documentation-oriented: - custom UI examples can still be improved, especially full end-to-end examples for bespoke login and registration screens -- passkey login currently handles the no-MFA and unsupported-browser paths cleanly, but there is still no bundled MFA continuation route -- some client methods intentionally return raw `Response` objects, so callers are responsible for checking `response.ok` and handling body parsing consistently +- there is no bundled MFA continuation route; login is not gated on a second factor today - public docs in sibling repos may still reflect older package behavior If you tackle one of these, keep the solution aligned with the existing public surface instead of reintroducing private screen-only helpers. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c87e66c..78796ce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,7 +53,7 @@ cp .env.example .env > Change the APP_ORIGIN env to `http://localhost:5173` to match vite. > The React SDK talks to a server adapter mounted at `/auth`, not directly to API auth cookies. -### If docker and docker compose are avaliable +### If docker and docker compose are available ```bash docker compose up -d @@ -95,7 +95,7 @@ curl http://localhost:5312/health/status ## 3. Create a Local Test Application -You will need a web application to integerate the SDK into. +You will need a web application to integrate the SDK into. We recommend using Vite for fast iteration: ```bash @@ -106,7 +106,7 @@ npm create vite@latest seamless-auth-dev ### Select React as the framework, Typescript as the variant ``` -> Web site will be active at http://localhost:5137 +> Web site will be active at http://localhost:5173 --- diff --git a/README.md b/README.md index 2ec6295..bd67a0a 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ - `useAuthClient()` - `usePasskeySupport()` - `hasScopedRole()` and `roleGrantsAccess()` -- types including `AuthContextType`, `Credential`, `User`, `OAuthProvider`, `StepUpStatus`, and the headless client input/result types +- `SeamlessAuthError`, the error type carried on a failed result +- types including `AuthContextType`, `Credential`, `User`, `OAuthProvider`, `StepUpStatus`, the `SeamlessAuthResult` wrapper, and the headless client input/result types ## Installation @@ -546,8 +547,9 @@ function CustomRegistration() { const [step, setStep] = useState<'details' | 'verify'>('details'); const [message, setMessage] = useState(''); - async function createAccount(email: string, phone: string) { - const { error } = await authClient.register({ email, phone }); + async function createAccount(email: string) { + // Registration needs only an email. A phone can be added and verified later. + const { error } = await authClient.register({ email }); if (error) { setMessage(error.message); @@ -783,15 +785,15 @@ The built-in flows assume compatible endpoints for: - `/webAuthn/login/finish` - `/webAuthn/register/start` - `/webAuthn/register/finish` -- `/otp/generate-phone-otp` -- `/otp/generate-email-otp` +- `POST /otp/generate-phone-otp` +- `POST /otp/generate-email-otp` - `/otp/verify-phone-otp` - `/otp/verify-email-otp` -- `/otp/generate-login-phone-otp` -- `/otp/generate-login-email-otp` +- `POST /otp/generate-login-phone-otp` +- `POST /otp/generate-login-email-otp` - `/otp/verify-login-phone-otp` - `/otp/verify-login-email-otp` -- `/magic-link` +- `POST /magic-link` - `/magic-link/check` - `/magic-link/verify/:token` - `/oauth/providers` @@ -814,6 +816,11 @@ The built-in flows assume compatible endpoints for: - `/organizations/:organizationId/members` - `/organizations/:organizationId/members/:userId` +The state-changing OTP and magic-link request routes are `POST` (marked above). They were previously +`GET`, which made them reachable as simple cross-site requests, so an `` tag could trigger SMS or +email sends to a signed-in user. Using `@seamless-auth/react` with an older adapter that only serves the +`GET` forms returns a 404 for those requests. See the changelog for the minimum adapter version. + ## Notes - This package does not create its own ``. diff --git a/RELEASES.md b/RELEASES.md index 08d213c..616290b 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -24,6 +24,16 @@ When changesets are merged to `main`, the workflow opens or updates a release PR Review that PR like a normal release artifact. When it is merged, the workflow publishes the npm package, creates the Git tag, and creates the GitHub Release. +## Adapter compatibility + +Some SDK changes require a matching `@seamless-auth/express` version, because the client and the +adapter share a route contract. Recent examples: the OTP generate and magic-link routes moved from +`GET` to `POST`, and the WebAuthn paths are casing sensitive. When a change touches request paths or +methods, the changeset states the minimum adapter version. + +When a change spans both repos, publish the adapter first, then the SDK. Publishing the SDK against an +older adapter leaves adopters with a 404 on the affected flow until a compatible adapter exists. + ## npm Publishing The workflow publishes with `NPM_CONFIG_PROVENANCE=true`, so npm records provenance for the package. diff --git a/tsconfig.build.json b/tsconfig.build.json index 4a44034..afc8cda 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -7,12 +7,6 @@ "sourceMap": true, "rootDir": "./src" }, - "include": [ - "src" - ], - "exclude": [ - "tests", - "**/*.test.ts", - "**/*.spec.ts" - ] + "include": ["src"], + "exclude": ["tests", "**/*.test.ts", "**/*.spec.ts"] }