Skip to content

Conversation

mandarini
Copy link
Contributor

What kind of change does this PR introduce?

Bug fix, feature, docs update, ...

What is the current behavior?

Please link any relevant issues here.

What is the new behavior?

Feel free to include screenshots if it includes visual changes.

Additional context

Add any other context or screenshots.

avallete and others added 30 commits January 16, 2025 09:55
chore: add test coverage to postgrest-js
When using MergeDeep type-fest even with simple structures we get this error
For typescript > 4.5.5 this trick fix the issue by forcing TS to infer the value
And reuse it instead of computing multiple time
…to refresh (supabase#1027)

When `autoRefreshToken` is off (or when a tab is in the background) but
`getSession()` is called -- such as in an active Realtime channel,
`getSession()` might return a JWT which will expire while the message is
travelling over the internet. There is one confirmed case of this
happening.

This PR adjusts this using the established `EXPIRY_MARGIN_MS` constant
(which only applies on initial initialization of the client). The
constant's value is brought in line with the `autoRefreshToken` ticks
which run every 30 seconds and refreshing is attempted 3 ticks prior to
the session expiring.

This means that JWTs with an expiry value **less than 90s** will always
refresh the session; which is acceptable.
🤖 I have created a release *beep* *boop*
---


##
[2.68.0](supabase/auth-js@v2.67.3...v2.68.0)
(2025-01-21)


### Features

* consider session expired with margin on getSession() without auto
refresh ([supabase#1027](supabase/auth-js#1027))
([a51dbb0](supabase/auth-js@a51dbb0))


### Bug Fixes

* remove `internal-types.ts`
([supabase#1014](supabase/auth-js#1014))
([902ec1d](supabase/auth-js@902ec1d))
* update docs to add scrypt
([supabase#1012](supabase/auth-js#1012))
([0dc969a](supabase/auth-js@0dc969a))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…on-error

fix(types): type instantiation is excessively deep and possibly infinite
## What kind of change does this PR introduce?

Bug fix

## What is the current behavior?

Type checking and/or linting does not pass for some configurations, per
supabase/auth-js#967 and
supabase/auth-js#1017

## What is the new behavior?

We're now asserting that `parts[1]` is a string (aka isn't undefined),
since we know from a previous check that the array length is 3.

## Additional context

Fixes #967 and fixes supabase#1017

Co-authored-by: Kang Ming <[email protected]>
remove client side check of jwt token
…1030)

## What kind of change does this PR introduce?
* `getClaims` supports verifying JWTs (both asymmetric and symmetric)
and returns the entire set of claims in the JWT payload

---------

Co-authored-by: Stojan Dimitrovski <[email protected]>
* fix: Change format of version sent

* get version from x-client-info header

* add tests

---------

Co-authored-by: Guilherme Souza <[email protected]>
- Allow to use returns at the end of the call chain after a .single()
- Add deprecation warning to move toward explicit overrideTypes method
- Add cast checking basic logic, an array should be declared if the result is an array, an object if the result is an object
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) and [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8). These dependencies needed to be updated together.

Updates `vitest` from 2.0.5 to 2.1.9
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v2.1.9/packages/vitest)

Updates `@vitest/coverage-v8` from 2.0.5 to 2.1.9
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v2.1.9/packages/coverage-v8)

---
updated-dependencies:
- dependency-name: vitest
  dependency-type: direct:development
- dependency-name: "@vitest/coverage-v8"
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [next](https://github.com/vercel/next.js) from 14.2.15 to 14.2.21.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](vercel/next.js@v14.2.15...v14.2.21)

---
updated-dependencies:
- dependency-name: next
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Deprecation of log_level to logLevel
* Exports type of log level supported
* Fixes log level being sent in URL params
* Changes heartbeat to default to 25s
xxRockOnxx and others added 26 commits September 17, 2025 12:33
* refactor: allow download as stream

* feat: fluent api for downloading as stream

* test: stream download error cases
* chore: do not fail on coveralls error

* chore: eol

---------

Co-authored-by: Bobbie Soedirgo <[email protected]>
🤖 I have created a release *beep* *boop*
---


##
[2.72.0](supabase/auth-js@v2.71.1...v2.72.0)
(2025-09-11)


### Features

* add sign in with ethereum to `signInWithWeb3`
([supabase#1082](supabase/auth-js#1082))
([33de908](supabase/auth-js@33de908))


### Bug Fixes

* correct typo in GoTrueClient initializePromise comment
([#1093](supabase/auth-js#1093))
([cf548f4](supabase/auth-js@cf548f4))
* docs for ethereum
([#1117](supabase/auth-js#1117))
([5792f70](supabase/auth-js@5792f70))
* update typedoc to 0.23
([#1113](supabase/auth-js#1113))
([d6d6be9](supabase/auth-js@d6d6be9))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
## What kind of change does this PR introduce?

Bug fix

## What is the current behavior?

Tests are failing because `jest-environment-jsdom` is not included as a
dependency, causing test environment setup issues with DOM-related
tests.

## What is the new behavior?

Added jest-environment-jsdom v28.1.3 as a devDependency to ensure tests
run properly with the jsdom environment configured.

## Additional context

The jest-environment-jsdom package was missing from the dependencies,
which caused tests that rely on DOM APIs to fail. This fix ensures the
proper test environment is available.
## What kind of change does this PR introduce?

This is a preparatory PR for adding webauthn support, which will have
different params/responses across the
`client.mfa.{enroll/challenge/verify}()` methods.

At the moment, some parameters in the calls are present in the type even
when they are not valid for that factor/method type, and the response
signature that the function returns does not match what's actually being
returned.

Also, in some instances of the types returned, we can assert some values
in the return types as being one property of the valid union types in
that property, for example:

in the call to `client.mfa.listFactors()` an object returns which
contains:`

```json
all: [],
totp: [],
phone: [],
```

If the developer tries to iterate through this list, the `factor_type`
will be a union of all the possible values in `.all`, and status will be
`verified | unverified` which is correct.
but in `.phone`, we *know* that it's of type `phone` and that its status
is `verified`, thus, we can assert this in the type, the `Factor`
signature has been updated to accept 2 generics (which are optional),
which enable us to set specific shapes in different parts of the
library, some other examples:

- In `.enroll()`, we *know* for a *fact* that the `.type()` of the
factor will match the `factorType` that was passed in the function call,
- Similarly, in the `AuthMFAChallengeResponse`, we *know* for a fact
that the `.type` property will always be `totp` or `phone` based on what
parameters were passed.

I believe these type revamps greately enhance the Developer Experience &
enable the developer to not make any mistakes while accessing those
fields.

It will also enable us to add specific documentation/links that will
appear in intellisense depending on which parameters were passed to each
function.

## What is the current behavior?

Most calls to the backend result in either:

```typescript
type ExampleCalltoT = {data: T, error: null} | {data: null, error: AuthError}
```

or

```typescript
type ExampleCalltoT = {data: T, error: null} | {data: ...keys of T set to null, error: AuthError}
```

Also, there was no distinction in calls to `.enroll()` and
`.challenge()`

## What is the new behavior?

- Consolidate response patterns into `RequestResult<T>` and
`RequestResultSafeDestructure<T>`
- Provide better type inference and IDE support with `Prettify<T>`
utility
- Add specific overloads to each function so that all the possible
parameters show up in the IDE, then narrow down as soon as you lock into
a specific parameter.
- Update AMR Methods to include everything that's supported by the
GoTrue backend.

### Key improvements

1. **Generic response utilities**:
   - `RequestResult<T>` - Standard result type with data/error pattern
- `RequestResultSafeDestructure<T>` - Allows safe destructuring with
null safety
- `Prettify<T>` - Improves IDE hover experience by resolving mapped
types

2. **Enhanced type safety**:
   - Stronger typing for MFA factor types using discriminated unions
   - Better type narrowing for factor verification status
   - Consistent error type handling across all responses

3. **Internally breaking change**:
- `_callRefreshToken` now returns `{ data: Session, error: null }`
instead of `{ session: Session, error: null }`, for consistency, this
will not affect users as it's an internal utility (tests have been
adjusted to accomodate this)

## Additional context

This refactoring improves developer experience by:

- Making response types more predictable and easier to work with
- Providing better IntelliSense/autocomplete in IDEs
- Reducing the likelihood of type-related bugs
- Making the codebase more maintainable

All existing tests pass with minimal adjustments to accommodate the
internal API change, and to prepare for the next PR here that adds
webauthn types, which require that some function calls have distinct
parameters/responses to not confuse users and guide them to use the
library correctly using the TYPES as a source of truth, so the developer
can use the api naturally just through the types.
Adds `linkIdentity()` method which allows passing OIDC credentials. The
ID token will be linked to the currently signed in user.

See also:
- supabase/auth#2108
## What kind of change does this PR introduce?

Add a `fail-on-error: false` to `coveralls` uploads. Change
`coverageapp` version used from `master` to `v2`, so that it accepts
this input.

## What is the current behavior?

Coveralls seems to be failing, and being flaky. 

## What is the new behavior?

If `coveralls` upload fails, the CI will not fail.
## What kind of change does this PR introduce?

**Feature** - This PR introduces YubiKey support for Multi-Factor
Authentication (MFA) via WebAuthn, enabling users to authenticate with
hardware security keys.

## What is the current behavior?

Currently, Supabase Auth JS supports two MFA methods:
  - TOTP (Time-based One-Time Password) authenticators
  - SMS-based verification
 
## What is the new behavior?

This PR adds full WebAuthn support to the authentication library, the
defaults enable yubikey support at the moment, but it allows the user to
override some parameters client-side to use other types of passkey
methods.

The PR adds the 'webauthn' factor type, to `listFactors`, `enroll()`,
`challenge()`, and `verify()`

(De)serialization of the webauthn reponse/credential object is done
behind the scenes via dedicated objects.

it also adds a new `experimental` namespace `.mfa.webauthn` which has a
`.register()` and `.authenticate()` methods, these methods allows
**single click** yubikey 2FA addition with a single function call.

additionally, we have `webauthn.{enroll|challenge|verify}()`, which
abstract away some of the logic surrounding enrollment, interaction with
the verifier, and have defaults for factortype etc.

### Two ways to use the new api:
#### Single Step
```typescript
const { data, error } = await client.mfa.webauthn.register({
				friendlyName: `Security Key ${new Date().toLocaleDateString()}`,
				rpId: window.location.hostname,
				rpOrigins: [window.location.origin]
			}, {
				authenticatorSelection: {
					authenticatorAttachment: 'platform',
					residentKey: 'discouraged',
					userVerification: 'discouraged',
					requireResidentKey: false
				}
			});

			if (error) throw error;

			console.log(data); // <- session
```
#### Multi Step Composition
```typescript
const { enroll, challenge, verify } = new WebAuthnApi(client);
		return enroll({
			friendlyName: params.friendlyName
		})
			.then(async ({ data, error }) => {
				if (!data) {
					throw error;
				}
				console.log(`enrolled factor, id: ${data.id}`, 'success');
				return await challenge({
					factorId: data?.id,
					webauthn: {
						rpId: params.rpId,
						rpOrigins: params.rpOrigins
					},
					signal: undefined
				});
			})
			.then(async ({ data, error }) => {
				if (!data) {
					throw error;
				}
				console.log(`challenged factor, id: ${data.factorId}`, 'success');
				return await verify({
					factorId: data.factorId,
					challengeId: data.challengeId,
					webauthn: {
						rpId: params.rpId,
						rpOrigins: params.rpOrigins,
						type: data.webauthn.type,
						credential_response: data.webauthn.credential_response
					}
				});
			})
			.then(({ data, error }) => {
				if (!data) {
					throw error;
				}
				console.log(`verified factor, id: ${data.access_token}`, 'success');
				return data;
			});
```

## Additional context

While this PR focuses on YubiKey support, the architecture is designed
to accommodate additional authenticator types in future releases
(platform authenticators, passkeys, etc.) without requiring significant
refactoring.

I've added `webauthn.dom.ts` and `webauthn.errors.ts` which attempt to
augment the typescript interfaces for webauthn since they are out of
date and there are some new features that its not aware of yet but are
publicly available in all major browsers.

For all such types, and due to the complexity of the API, I've added
comprehensive jsdocs for each parameter with reference to the w3a spec
for reference on their usage.

in all webauthn related methods, I've added the ability to **override**
any of the parameters we pass by default to the
`credentials.{get|create}()` method for convenience.

This PR is dependent on my previous PR for streamlining types
supabase/auth-js#1116

and this PR for `auth` supabase/auth#2163

---------

Co-authored-by: Stojan Dimitrovski <[email protected]>
@mandarini mandarini self-assigned this Oct 1, 2025
@mandarini mandarini closed this Oct 1, 2025
Copy link

snyk-io bot commented Oct 1, 2025

Snyk checks have failed. 5 issues have been found so far.

Icon Severity Issues
Critical 0
High 0
Medium 5
Low 0

code/snyk check is complete. 5 issues have been found. (View Details)

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

try {
// Change to auth-js directory and publish
process.chdir(authJsDir)
execSync(publishCommand, { stdio: 'inherit' })
Copy link

Choose a reason for hiding this comment

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

  Command Injection

Unsanitized input from a command line argument flows into child_process.execSync, where it is used to build a shell command. Forwarding command-line arguments or file paths from the local environment to a function that executes a system command can change the meaning of the command unexpectedly due to unescaped special characters, which may result in a Indirect Command Injection vulnerability.

Line 112 | CWE-78 | Priority score 504 | Learn more about this vulnerability
Data flow: 12 steps

Step 1 - 4

return process.argv[idx + 1]

Step 5 - 7 scripts/publish-gotrue-legacy.ts#L49

Step 8 - 10 scripts/publish-gotrue-legacy.ts#L103

Step 11 - 12

execSync(publishCommand, { stdio: 'inherit' })

const branchName = `release-${version}`

try {
execSync(`git checkout -b ${branchName}`)
Copy link

Choose a reason for hiding this comment

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

  Command Injection

Unsanitized input from a command line argument flows into child_process.execSync, where it is used to build a shell command. Forwarding command-line arguments or file paths from the local environment to a function that executes a system command can change the meaning of the command unexpectedly due to unescaped special characters, which may result in a Indirect Command Injection vulnerability.

Line 72 | CWE-78 | Priority score 554 | Learn more about this vulnerability
Data flow: 34 steps

Step 1 - 4

return process.argv[idx + 1] // next token

Step 5 - 7 scripts/release-stable.ts#L13

Step 8 - 9 scripts/release-stable.ts#L30

Step 10 - 14 scripts/release-stable.ts#L26

Step 15 scripts/release-stable.ts#L44

Step 16 - 19 scripts/release-stable.ts#L42

Step 20 - 28 scripts/release-stable.ts#L68

Step 29 - 31 scripts/release-stable.ts#L69

Step 32 - 34

execSync(`git checkout -b ${branchName}`)


// Commit changes if any
try {
execSync(`git commit -m "chore(release): publish version ${version}"`)
Copy link

Choose a reason for hiding this comment

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

  Command Injection

Unsanitized input from a command line argument flows into child_process.execSync, where it is used to build a shell command. Forwarding command-line arguments or file paths from the local environment to a function that executes a system command can change the meaning of the command unexpectedly due to unescaped special characters, which may result in a Indirect Command Injection vulnerability.

Line 78 | CWE-78 | Priority score 554 | Learn more about this vulnerability
Data flow: 31 steps

Step 1 - 4

return process.argv[idx + 1] // next token

Step 5 - 7 scripts/release-stable.ts#L13

Step 8 - 9 scripts/release-stable.ts#L30

Step 10 - 14 scripts/release-stable.ts#L26

Step 15 scripts/release-stable.ts#L44

Step 16 - 19 scripts/release-stable.ts#L42

Step 20 - 28 scripts/release-stable.ts#L68

Step 29 - 31

execSync(`git commit -m "chore(release): publish version ${version}"`)

console.log('No changes to commit')
}

execSync(`git push origin ${branchName}`)
Copy link

Choose a reason for hiding this comment

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

  Command Injection

Unsanitized input from a command line argument flows into child_process.execSync, where it is used to build a shell command. Forwarding command-line arguments or file paths from the local environment to a function that executes a system command can change the meaning of the command unexpectedly due to unescaped special characters, which may result in a Indirect Command Injection vulnerability.

Line 83 | CWE-78 | Priority score 554 | Learn more about this vulnerability
Data flow: 34 steps

Step 1 - 4

return process.argv[idx + 1] // next token

Step 5 - 7 scripts/release-stable.ts#L13

Step 8 - 9 scripts/release-stable.ts#L30

Step 10 - 14 scripts/release-stable.ts#L26

Step 15 scripts/release-stable.ts#L44

Step 16 - 19 scripts/release-stable.ts#L42

Step 20 - 28 scripts/release-stable.ts#L68

Step 29 - 31 scripts/release-stable.ts#L69

Step 32 - 34

execSync(`git push origin ${branchName}`)

execSync(`git push origin ${branchName}`)

// Open PR using GitHub CLI
execSync(
Copy link

Choose a reason for hiding this comment

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

  Command Injection

Unsanitized input from a command line argument flows into child_process.execSync, where it is used to build a shell command. Forwarding command-line arguments or file paths from the local environment to a function that executes a system command can change the meaning of the command unexpectedly due to unescaped special characters, which may result in a Indirect Command Injection vulnerability.

Line 86 | CWE-78 | Priority score 554 | Learn more about this vulnerability
Data flow: 34 steps

Step 1 - 4

return process.argv[idx + 1] // next token

Step 5 - 7 scripts/release-stable.ts#L13

Step 8 - 9 scripts/release-stable.ts#L30

Step 10 - 14 scripts/release-stable.ts#L26

Step 15 scripts/release-stable.ts#L44

Step 16 - 19 scripts/release-stable.ts#L42

Step 20 - 28 scripts/release-stable.ts#L68

Step 29 - 31 scripts/release-stable.ts#L69

Step 32 - 33 scripts/release-stable.ts#L87

Step 34

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.