Skip to content

Commit 0f42139

Browse files
committed
fix(auth): upgrade Better Auth to 1.7.2
1 parent 3c3e07a commit 0f42139

18 files changed

Lines changed: 356 additions & 223 deletions

File tree

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ GOOGLE_CLIENT_SECRET=""
5353
# MICROSOFT_CLIENT_SECRET=""
5454

5555
# Optional. Enables Slack account linking on Settings > Connections.
56-
# Add APP_URL + /api/auth/oauth2/callback/slack as the Slack OAuth redirect URL.
56+
# Add API_URL + /api/auth/callback/slack as the Slack OAuth redirect URL.
5757
# SLACK_CLIENT_ID=""
5858
# SLACK_CLIENT_SECRET=""
5959

apps/agent/test/slack-membership.integration.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ async function connect() {
2424
where: { id: ACCOUNT_ID },
2525
create: {
2626
id: ACCOUNT_ID,
27+
issuer: "local:oauth:slack",
2728
accountId: "T-JOIN-SPEC",
2829
providerId: "slack",
2930
userId: USER_ID,

apps/agent/test/slack-people.integration.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ async function connect() {
2727
where: { id: ACCOUNT_ID },
2828
create: {
2929
id: ACCOUNT_ID,
30+
issuer: "local:oauth:slack",
3031
accountId: "T-SPEC",
3132
providerId: "slack",
3233
userId: USER_ID,

apps/api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"@thallesp/nestjs-better-auth": "^2.7.0",
3939
"@trpc/server": "^11.18.0",
4040
"@vercel/blob": "^2.6.1",
41-
"better-auth": "^1.6.25",
41+
"better-auth": "^1.7.2",
4242
"cache-manager": "^7.2.9",
4343
"class-transformer": "^0.5.1",
4444
"class-validator": "^0.15.1",

apps/api/src/mailbox/mailbox-token.service.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,17 @@ export class MailboxTokenService {
7272
source: SyncSource,
7373
): Promise<TokenResult> {
7474
const providerId = PROVIDER_FOR_SOURCE[source];
75-
76-
if (!(await this.isConnected(userId, source))) {
75+
const account = await this.db.account.findFirst({
76+
where: { userId, providerId },
77+
select: { id: true, scope: true },
78+
});
79+
if (!account) {
80+
return {
81+
outcome: "needs-reconnect",
82+
reason: `${label(providerId)} has no connected account.`,
83+
};
84+
}
85+
if (!parseScopes(account.scope).has(SCOPE_FOR_SOURCE[source])) {
7786
return {
7887
outcome: "not-connected",
7988
reason: `The ${source} scope has not been granted.`,
@@ -82,7 +91,7 @@ export class MailboxTokenService {
8291

8392
try {
8493
const { accessToken } = await auth.api.getAccessToken({
85-
body: { providerId, userId },
94+
body: { accountId: account.id, userId },
8695
});
8796

8897
if (!accessToken) {

apps/api/test/mailbox-purge.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ describe("disconnecting Microsoft", () => {
290290
await db.account.create({
291291
data: {
292292
id: `ms-${suffix}`,
293+
issuer: `https://login.microsoftonline.com/${suffix}/v2.0`,
293294
accountId: `ms-account-${suffix}`,
294295
providerId: MICROSOFT_PROVIDER_ID,
295296
userId: outlookRep,
@@ -349,6 +350,7 @@ describe("disconnecting Google", () => {
349350
await db.account.create({
350351
data: {
351352
id: `goog-${suffix}`,
353+
issuer: "https://accounts.google.com",
352354
accountId: `goog-account-${suffix}`,
353355
providerId: GOOGLE_PROVIDER_ID,
354356
userId: gmailRep,

apps/app/app/(app)/[slug]/settings/connections/slack/slack-connect-button.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ const CONNECT_ERRORS = new Map([
3030

3131
async function startSlackOAuth(slug: string) {
3232
try {
33-
const { error } = await authClient.oauth2.link({
34-
providerId: "slack",
33+
const { error } = await authClient.linkSocial({
34+
provider: "slack",
3535
callbackURL: `${window.location.origin}/${slug}/settings/connections/slack/people`,
3636
errorCallbackURL: `${window.location.origin}/${slug}/settings/connections/slack?provider=slack`,
3737
});

apps/app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"@trpc/server": "^11.18.0",
2727
"@trpc/tanstack-react-query": "^11.18.0",
2828
"api": "workspace:*",
29-
"better-auth": "^1.6.25",
29+
"better-auth": "^1.7.2",
3030
"eve": "^0.29.4",
3131
"next": "16.3.0",
3232
"next-themes": "^0.4.6",

bun.lock

Lines changed: 52 additions & 118 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/connections.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,22 @@ undo it.
4545
Connecting is the same decision as disconnecting, because `replaceSlackConnection`
4646
deletes every other Slack account row: a second person connecting *replaces* the
4747
workspace's Slack, and every deployed agent then reads from and posts to whichever
48-
Slack they installed. Hiding the button is not enough`authClient.oauth2.link`
49-
is one POST.
48+
Slack they installed. Hiding the button is not enough. `authClient.linkSocial`
49+
sends one POST.
5050

5151
`slackConnectGuard` (`packages/auth/src/slack-connect.ts`) is Better Auth's
5252
`hooks.before`, and it asks the same `canManageConnections` the API does. It
53-
covers all three doors: `/oauth2/link`, `/sign-in/oauth2` (Slack is a connection,
54-
never a sign-in method, and that endpoint needs no session) and
55-
`/oauth2/callback/slack`. The callback is the one that matters — refusing there
56-
happens **before the code is exchanged**, so a refused attempt writes no
53+
guards Slack account-linking starts through `/link-social`. Public Slack sign-in
54+
starts through `/sign-in/social` remain available to Better Auth. The guard also
55+
reads the server-generated OAuth state before `/callback/slack`. It guards the
56+
callback only when that state identifies an account-linking transaction. A
57+
normal Slack sign-in callback remains available to Better Auth. The callback
58+
check happens before Better Auth exchanges the code. A refused link writes no
5759
`SlackWorkspaceGrant` user token and deletes no bot token. Google and Microsoft
58-
sign in on different paths and never reach the guard.
60+
callbacks never reach the Slack guard.
61+
62+
Existing Slack applications must replace `/api/auth/oauth2/callback/slack` with
63+
`/api/auth/callback/slack` before this upgrade reaches production.
5964

6065
A workspace with no owner and no admin lets any member connect. There is nobody
6166
left to ask, and a fresh install must not be locked out of its first connection.

0 commit comments

Comments
 (0)