Skip to content

Commit 1daf0f3

Browse files
committed
refactor: move to util reusable account auth info
1 parent b46fdd6 commit 1daf0f3

File tree

2 files changed

+42
-58
lines changed

2 files changed

+42
-58
lines changed

src/lib/auth/auth.ts

Lines changed: 5 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ import {
1111
OIDC_CLIENT_SECRET,
1212
OIDC_ISSUER_URL,
1313
OIDC_PROVIDER_ID,
14-
TOKEN_ONE_HOUR_MS,
1514
TOKEN_SEVEN_DAYS_SECONDS,
1615
TRUSTED_ORIGINS,
1716
} from "./constants";
1817
import type { OIDCDiscovery, OidcTokenData, TokenResponse } from "./types";
19-
import { decrypt, encrypt } from "./utils";
18+
import { decrypt, encrypt, saveAccountToken } from "./utils";
2019

2120
/**
2221
* Cached token endpoint to avoid repeated discovery calls.
@@ -25,8 +24,9 @@ let cachedTokenEndpoint: string | null = null;
2524

2625
/**
2726
* Saves encrypted token data in HTTP-only cookie.
27+
* Exported for use by saveAccountToken in utils.
2828
*/
29-
async function saveTokenCookie(tokenData: OidcTokenData): Promise<void> {
29+
export async function saveTokenCookie(tokenData: OidcTokenData): Promise<void> {
3030
const encrypted = await encrypt(tokenData, BETTER_AUTH_SECRET);
3131
const cookieStore = await cookies();
3232

@@ -187,63 +187,10 @@ export const auth: Auth<BetterAuthOptions> = betterAuth({
187187
databaseHooks: {
188188
account: {
189189
create: {
190-
after: async (account: {
191-
accessToken?: string | null;
192-
refreshToken?: string | null;
193-
accessTokenExpiresAt?: Date | string | null;
194-
refreshTokenExpiresAt?: Date | string | null;
195-
userId: string;
196-
}) => {
197-
if (account.accessToken && account.userId) {
198-
const expiresAt = account.accessTokenExpiresAt
199-
? new Date(account.accessTokenExpiresAt).getTime()
200-
: Date.now() + TOKEN_ONE_HOUR_MS;
201-
202-
const refreshTokenExpiresAt = account.refreshTokenExpiresAt
203-
? new Date(account.refreshTokenExpiresAt).getTime()
204-
: undefined;
205-
206-
const tokenData: OidcTokenData = {
207-
accessToken: account.accessToken,
208-
refreshToken: account.refreshToken || undefined,
209-
expiresAt,
210-
refreshTokenExpiresAt,
211-
userId: account.userId,
212-
};
213-
214-
await saveTokenCookie(tokenData);
215-
}
216-
},
190+
after: saveAccountToken,
217191
},
218192
update: {
219-
after: async (account: {
220-
accessToken?: string | null;
221-
refreshToken?: string | null;
222-
accessTokenExpiresAt?: Date | string | null;
223-
refreshTokenExpiresAt?: Date | string | null;
224-
userId: string;
225-
}) => {
226-
// Same logic as create - save tokens on re-login
227-
if (account.accessToken && account.userId) {
228-
const expiresAt = account.accessTokenExpiresAt
229-
? new Date(account.accessTokenExpiresAt).getTime()
230-
: Date.now() + TOKEN_ONE_HOUR_MS;
231-
232-
const refreshTokenExpiresAt = account.refreshTokenExpiresAt
233-
? new Date(account.refreshTokenExpiresAt).getTime()
234-
: undefined;
235-
236-
const tokenData: OidcTokenData = {
237-
accessToken: account.accessToken,
238-
refreshToken: account.refreshToken || undefined,
239-
expiresAt,
240-
refreshTokenExpiresAt,
241-
userId: account.userId,
242-
};
243-
244-
await saveTokenCookie(tokenData);
245-
}
246-
},
193+
after: saveAccountToken,
247194
},
248195
},
249196
},

src/lib/auth/utils.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import { createHash } from "node:crypto";
66
import * as jose from "jose";
7+
import { TOKEN_ONE_HOUR_MS } from "./constants";
78
import type { OidcTokenData } from "./types";
89

910
/**
@@ -87,3 +88,39 @@ export function isOidcTokenData(data: unknown): data is OidcTokenData {
8788
typeof obj.refreshTokenExpiresAt === "number")
8889
);
8990
}
91+
92+
/**
93+
* Saves OIDC tokens from account creation or update into HTTP-only cookie.
94+
* Used by Better Auth database hooks for both initial login and re-login.
95+
*
96+
* @param account - Account data from Better Auth containing OIDC tokens
97+
*/
98+
export async function saveAccountToken(account: {
99+
accessToken?: string | null;
100+
refreshToken?: string | null;
101+
accessTokenExpiresAt?: Date | string | null;
102+
refreshTokenExpiresAt?: Date | string | null;
103+
userId: string;
104+
}) {
105+
if (account.accessToken && account.userId) {
106+
const expiresAt = account.accessTokenExpiresAt
107+
? new Date(account.accessTokenExpiresAt).getTime()
108+
: Date.now() + TOKEN_ONE_HOUR_MS;
109+
110+
const refreshTokenExpiresAt = account.refreshTokenExpiresAt
111+
? new Date(account.refreshTokenExpiresAt).getTime()
112+
: undefined;
113+
114+
const tokenData: OidcTokenData = {
115+
accessToken: account.accessToken,
116+
refreshToken: account.refreshToken || undefined,
117+
expiresAt,
118+
refreshTokenExpiresAt,
119+
userId: account.userId,
120+
};
121+
122+
// Dynamic import to avoid circular dependency
123+
const { saveTokenCookie } = await import("./auth");
124+
await saveTokenCookie(tokenData);
125+
}
126+
}

0 commit comments

Comments
 (0)