v1.3.8#4410
Conversation
Co-authored-by: KinfeMichael Tariku <65047246+Kinfe123@users.noreply.github.com>
Co-authored-by: KinfeMichael Tariku <65047246+Kinfe123@users.noreply.github.com> Co-authored-by: Kinfe123 <kinfishtech@gmail.com>
Co-authored-by: Maxwell <145994855+ping-maxwell@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
# Conflicts: # demo/nextjs/package.json # docs/package.json # packages/better-auth/package.json # pnpm-lock.yaml
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
better-auth
@better-auth/cli
@better-auth/expo
@better-auth/sso
@better-auth/stripe
commit: |
There was a problem hiding this comment.
40 issues found across 275 files
Note: This PR contains a large number of files. cubic only reviews up to 150 files per PR, so some files may not have been reviewed.
React with 👍 or 👎 to teach cubic. You can also tag @cubic-dev-ai to give feedback, ask questions, or re-run the review.
| "mongodb": "^6.18.0", | ||
| "mysql2": "^3.14.3", | ||
| "next": "^15.5.0", | ||
| "ms": "4.0.0-nightly.202508271359", |
There was a problem hiding this comment.
ms is a runtime dependency (imported and used in runtime code) but is declared under devDependencies; consumers will hit a missing module at runtime. Move ms to dependencies.
Prompt for AI agents
Address the following comment on packages/better-auth/package.json at line 742:
<comment>ms is a runtime dependency (imported and used in runtime code) but is declared under devDependencies; consumers will hit a missing module at runtime. Move ms to dependencies.</comment>
<file context>
@@ -717,15 +732,16 @@
"mongodb": "^6.18.0",
- "mysql2": "^3.14.3",
- "next": "^15.5.0",
+ "ms": "4.0.0-nightly.202508271359",
+ "mysql2": "^3.14.4",
+ "next": "^15.5.2",
</file context>
| @@ -0,0 +1,30 @@ | |||
| import { betterAuth } from "better-auth"; | |||
| import { DatabaseSync } from "node:sqlite"; | |||
There was a problem hiding this comment.
Importing from "node:sqlite" will fail to resolve when run under Deno because there is no core module or alias for this specifier; the server will crash at startup.
Prompt for AI agents
Address the following comment on e2e/smoke/test/fixtures/deno-simple.ts at line 2:
<comment>Importing from "node:sqlite" will fail to resolve when run under Deno because there is no core module or alias for this specifier; the server will crash at startup.</comment>
<file context>
@@ -0,0 +1,30 @@
+import { betterAuth } from "better-auth";
+import { DatabaseSync } from "node:sqlite";
+import { getMigrations } from "better-auth/db";
+
</file context>
| } | ||
| } | ||
| if (authentication === "basic") { | ||
| const encodedCredentials = base64Url.encode( |
There was a problem hiding this comment.
Basic Authorization must use standard Base64, not base64url; this will cause authentication failures with most OAuth2 providers when authentication === "basic".
Prompt for AI agents
Address the following comment on packages/better-auth/src/oauth2/client-credentials-token.ts at line 35:
<comment>Basic Authorization must use standard Base64, not base64url; this will cause authentication failures with most OAuth2 providers when authentication === "basic".</comment>
<file context>
@@ -0,0 +1,97 @@
+ }
+ }
+ if (authentication === "basic") {
+ const encodedCredentials = base64Url.encode(
+ `${options.clientId}:${options.clientSecret}`,
+ );
</file context>
| ], | ||
| }) | ||
| .catch((error) => { | ||
| ctx.logger.error(`Failed to delete expired API keys:`, error); |
There was a problem hiding this comment.
Errors are logged but not rethrown in the catch block, causing the function to resolve successfully even if deleteMany fails; this hides failures and changes previous error propagation behavior.
(Based on previous feedback about ensuring all async operations have proper error handling.)
Prompt for AI agents
Address the following comment on packages/better-auth/src/plugins/api-key/routes/index.ts at line 69:
<comment>Errors are logged but not rethrown in the catch block, causing the function to resolve successfully even if deleteMany fails; this hides failures and changes previous error propagation behavior.
(Based on previous feedback about ensuring all async operations have proper error handling.)</comment>
<file context>
@@ -64,10 +64,10 @@ export function deleteAllExpiredApiKeys(
],
+ })
+ .catch((error) => {
+ ctx.logger.error(`Failed to delete expired API keys:`, error);
});
- } catch (error) {
</file context>
| async sendInvitationEmail(data) { | ||
| // ... your invitation email logic | ||
| }, | ||
| async onInvitationAccepted(data) { |
There was a problem hiding this comment.
Documents an unsupported config option onInvitationAccepted; use organizationHooks.afterAcceptInvitation instead.
Prompt for AI agents
Address the following comment on docs/content/docs/plugins/organization.mdx at line 948:
<comment>Documents an unsupported config option onInvitationAccepted; use organizationHooks.afterAcceptInvitation instead.</comment>
<file context>
@@ -589,21 +916,52 @@ type acceptInvitation = {
+ async sendInvitationEmail(data) {
+ // ... your invitation email logic
+ },
+ async onInvitationAccepted(data) {
+ // This callback gets triggered when an invitation is accepted
+ },
</file context>
| const charset = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; | ||
| let code = ""; | ||
| for (let i = 0; i < 8; i++) { | ||
| code += charset[Math.floor(Math.random() * charset.length)]; |
There was a problem hiding this comment.
Insecure randomness for user code generation; use a cryptographically secure RNG to reduce guessability.
Prompt for AI agents
Address the following comment on docs/content/docs/plugins/device-authorization.mdx at line 397:
<comment>Insecure randomness for user code generation; use a cryptographically secure RNG to reduce guessability.</comment>
<file context>
@@ -0,0 +1,661 @@
+ const charset = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
+ let code = "";
+ for (let i = 0; i < 8; i++) {
+ code += charset[Math.floor(Math.random() * charset.length)];
+ }
+ return code;
</file context>
| page: Page, | ||
| fn: ({ client }: { client: Window["client"] }) => R, | ||
| ): Promise<R> { | ||
| const client = await page.evaluateHandle<Window["client"]>("window.client"); |
There was a problem hiding this comment.
JSHandle created for window.client is never disposed, which can leak resources across tests.
Prompt for AI agents
Address the following comment on e2e/integration/vanilla-node/e2e/utils.ts at line 20:
<comment>JSHandle created for window.client is never disposed, which can leak resources across tests.</comment>
<file context>
@@ -0,0 +1,82 @@
+ page: Page,
+ fn: ({ client }: { client: Window["client"] }) => R,
+): Promise<R> {
+ const client = await page.evaluateHandle<Window["client"]>("window.client");
+ return page.evaluate(fn, { client });
+}
</file context>
|
|
||
| setError(null); | ||
|
|
||
| startDenyTransition(async () => { |
There was a problem hiding this comment.
Async useTransition callback won’t track the pending async work; isDenyPending likely never reflects the request, so the Deny button may not disable or show a spinner.
Prompt for AI agents
Address the following comment on demo/nextjs/app/device/approve/page.tsx at line 42:
<comment>Async useTransition callback won’t track the pending async work; isDenyPending likely never reflects the request, so the Deny button may not disable or show a spinner.</comment>
<file context>
@@ -0,0 +1,122 @@
+
+ setError(null);
+
+ startDenyTransition(async () => {
+ try {
+ await client.device.deny({
</file context>
|
|
||
| setError(null); | ||
|
|
||
| startApproveTransition(async () => { |
There was a problem hiding this comment.
Async useTransition callback won’t track the pending async work; isApprovePending likely never reflects the request, so the Approve button may not disable or show a spinner.
Prompt for AI agents
Address the following comment on demo/nextjs/app/device/approve/page.tsx at line 25:
<comment>Async useTransition callback won’t track the pending async work; isApprovePending likely never reflects the request, so the Approve button may not disable or show a spinner.</comment>
<file context>
@@ -0,0 +1,122 @@
+
+ setError(null);
+
+ startApproveTransition(async () => {
+ try {
+ await client.device.approve({
</file context>
| To list the organizations that a user is a member of, you can use `useListOrganizations` hook. It implements a reactive way to get the organizations that the user is a member of. | ||
|
|
||
| <Tabs items={["React", "Vue", "Svelte"]} defaultValue="React"> | ||
| <Tabs items={["React", "Vue", "Svelte"]} default="React"> |
There was a problem hiding this comment.
Tabs component likely expects defaultValue, not default; this will break default tab selection.
Prompt for AI agents
Address the following comment on docs/content/docs/plugins/organization.mdx at line 516:
<comment>Tabs component likely expects defaultValue, not default; this will break default tab selection.</comment>
<file context>
@@ -137,75 +141,391 @@ type checkOrganizationSlug = {
To list the organizations that a user is a member of, you can use `useListOrganizations` hook. It implements a reactive way to get the organizations that the user is a member of.
-<Tabs items={["React", "Vue", "Svelte"]} defaultValue="React">
+<Tabs items={["React", "Vue", "Svelte"]} default="React">
<Tab value="React">
```tsx title="client.tsx"
</file context>
| <Tabs items={["React", "Vue", "Svelte"]} default="React"> | |
| <Tabs items={["React", "Vue", "Svelte"]} defaultValue="React"> |
|
Remind to use |
Co-authored-by: Alex Yang <himself65@outlook.com>
v1.3.8
🚀 Features
for TV apps and CLI tools
🐞 Bug Fixes
📚 Documentation
🔧 Developer Experience