Skip to content

Commit 7af2a78

Browse files
committed
refactor: better-auth
Signed-off-by: Innei <[email protected]>
1 parent c1e3c4d commit 7af2a78

File tree

15 files changed

+659
-467
lines changed

15 files changed

+659
-467
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
},
3030
"dependencies": {
3131
"@antv/g2": "^4.2.11",
32-
"@auth/core": "0.34.2",
3332
"@bytebase/vue-kbar": "0.1.8",
3433
"@codemirror/commands": "6.7.1",
3534
"@codemirror/lang-markdown": "6.3.1",
@@ -57,6 +56,7 @@
5756
"@xterm/addon-fit": "0.10.0",
5857
"@xterm/xterm": "5.5.0",
5958
"ansi_up": "6.0.2",
59+
"better-auth": "1.0.4",
6060
"blurhash": "2.0.5",
6161
"buffer": "6.0.3",
6262
"canvas-confetti": "1.9.3",
@@ -131,4 +131,4 @@
131131
"windicss": "3.5.6"
132132
},
133133
"packageManager": "[email protected]"
134-
}
134+
}

pnpm-lock.yaml

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

src/components/config-form/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { O } from 'crossbell.js/dist/index-LKLW_17H'
21
import { get, set } from 'lodash-es'
32
import { marked } from 'marked'
43
import {

src/components/sidebar/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { RouteName } from '~/router/name'
1818
import { AppStore } from '~/stores/app'
1919
import { UIStore } from '~/stores/ui'
2020
import { removeToken, RESTManager } from '~/utils'
21-
import { signOut } from '~/utils/authjs'
21+
import { authClient } from '~/utils/authjs/auth'
2222

2323
import { configs } from '../../configs'
2424
import { useStoreRef } from '../../hooks/use-store-ref'
@@ -308,7 +308,7 @@ const LogoutAvatarButton = defineComponent({
308308
e.stopPropagation()
309309
await RESTManager.api.user.logout.post({})
310310
removeToken()
311-
await signOut()
311+
await authClient.signOut()
312312
router.push({
313313
name: RouteName.Login,
314314
})

src/main.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,6 @@ import './index.css'
1414

1515
import { router } from './router'
1616
import { attachTokenFromQuery, RESTManager } from './utils'
17-
import { authConfigManager, getCsrfToken } from './utils/authjs'
18-
19-
authConfigManager.setConfig({
20-
basePath: '/auth',
21-
baseUrl: RESTManager.endpoint,
22-
credentials: 'include',
23-
})
2417

2518
attachTokenFromQuery()
2619

src/utils/authjs/auth.ts

Lines changed: 24 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -1,188 +1,24 @@
1-
import type {
2-
BuiltInProviderType,
3-
RedirectableProviderType,
4-
} from '@auth/core/providers'
5-
import type {
6-
AuthClientConfig,
7-
ClientSafeProvider,
8-
LiteralUnion,
9-
SignInAuthorizationParams,
10-
SignInOptions,
11-
SignInResponse,
12-
SignOutParams,
13-
SignOutResponse,
14-
} from './client'
15-
16-
import { fetchData, parseUrl } from './client'
17-
18-
class AuthConfigManager {
19-
private static instance: AuthConfigManager | null = null
20-
_config: AuthClientConfig = {
21-
baseUrl:
22-
typeof window !== 'undefined'
23-
? parseUrl(window.location.origin).origin
24-
: '',
25-
basePath:
26-
typeof window !== 'undefined'
27-
? parseUrl(window.location.origin).path
28-
: '/api/auth',
29-
credentials: 'same-origin',
30-
_lastSync: 0,
31-
_session: undefined,
32-
_getSession: () => {},
33-
}
34-
35-
static getInstance(): AuthConfigManager {
36-
if (!AuthConfigManager.instance) {
37-
AuthConfigManager.instance = new AuthConfigManager()
38-
}
39-
return AuthConfigManager.instance
40-
}
41-
42-
setConfig(userConfig: Partial<AuthClientConfig>): void {
43-
this._config = { ...this._config, ...userConfig }
44-
}
45-
46-
getConfig(): AuthClientConfig {
47-
return this._config
48-
}
49-
}
50-
51-
export const authConfigManager = AuthConfigManager.getInstance()
52-
type ProvidersType = Record<
53-
LiteralUnion<BuiltInProviderType>,
54-
ClientSafeProvider
55-
>
56-
57-
export async function getProviders() {
58-
return fetchData<ProvidersType>('providers', authConfigManager.getConfig())
59-
}
60-
61-
export async function getCsrfToken() {
62-
const response = await fetchData<{ csrfToken: string }>(
63-
'csrf',
64-
authConfigManager.getConfig(),
65-
)
66-
return response?.csrfToken ?? ''
67-
}
68-
69-
export async function signIn<
70-
P extends RedirectableProviderType | undefined = undefined,
71-
>(
72-
provider?: LiteralUnion<
73-
P extends RedirectableProviderType
74-
? P | BuiltInProviderType
75-
: BuiltInProviderType
76-
>,
77-
options?: SignInOptions,
78-
authorizationParams?: SignInAuthorizationParams,
79-
): Promise<
80-
P extends RedirectableProviderType ? SignInResponse | undefined : undefined
81-
> {
82-
const { callbackUrl = window.location.href, redirect = true } = options ?? {}
83-
84-
const __AUTHJS: AuthClientConfig = authConfigManager.getConfig()
85-
86-
const href = `${__AUTHJS.baseUrl}${__AUTHJS.basePath}`
87-
88-
const providers = await getProviders()
89-
90-
if (!providers) {
91-
window.location.href = `${href}/error`
92-
return
93-
}
94-
95-
if (!provider || !(provider in providers)) {
96-
window.location.href = `${href}/signin?${new URLSearchParams({
97-
callbackUrl,
98-
})}`
99-
return
100-
}
101-
102-
const isCredentials = providers[provider].type === 'credentials'
103-
const isEmail = providers[provider].type === 'email'
104-
const isSupportingReturn = isCredentials || isEmail
105-
106-
const signInUrl = `${href}/${
107-
isCredentials ? 'callback' : 'signin'
108-
}/${provider}`
109-
110-
const csrfToken = await getCsrfToken()
111-
const res = await fetch(
112-
`${signInUrl}?${new URLSearchParams(authorizationParams)}`,
113-
{
114-
method: 'post',
115-
headers: {
116-
'Content-Type': 'application/x-www-form-urlencoded',
117-
'X-Auth-Return-Redirect': '1',
118-
},
119-
// @ts-expect-error TODO: Fix this
120-
body: new URLSearchParams({ ...options, csrfToken, callbackUrl }),
121-
credentials: __AUTHJS.credentials,
122-
},
123-
)
124-
125-
const data = await res.json()
126-
127-
// TODO: Do not redirect for Credentials and Email providers by default in next major
128-
if (redirect || !isSupportingReturn) {
129-
const url = (data as any).url ?? callbackUrl
130-
window.location.href = url
131-
// If url contains a hash, the browser does not reload the page. We reload manually
132-
if (url.includes('#')) {
133-
window.location.reload()
134-
}
135-
return
136-
}
137-
138-
const error = new URL((data as any).url).searchParams.get('error')
139-
140-
if (res.ok) {
141-
await __AUTHJS._getSession({ event: 'storage' })
142-
}
143-
144-
return {
145-
error,
146-
status: res.status,
147-
ok: res.ok,
148-
url: error ? null : (data as any).url,
149-
} as any
150-
}
151-
152-
/**
153-
* Initiate a signout, by destroying the current session.
154-
* Handles CSRF protection.
155-
*/
156-
export async function signOut<R extends boolean = true>(
157-
options?: SignOutParams<R>,
158-
): Promise<R extends true ? undefined : SignOutResponse> {
159-
const { callbackUrl = window.location.href } = options ?? {}
160-
const __AUTHJS: AuthClientConfig = authConfigManager.getConfig()
161-
const href = `${__AUTHJS.baseUrl}${__AUTHJS.basePath}`
162-
const csrfToken = await getCsrfToken()
163-
const res = await fetch(`${href}/signout`, {
164-
method: 'post',
165-
headers: {
166-
'Content-Type': 'application/x-www-form-urlencoded',
167-
'X-Auth-Return-Redirect': '1',
168-
},
169-
body: new URLSearchParams({ csrfToken, callbackUrl }),
170-
credentials: __AUTHJS.credentials,
171-
})
172-
const data = await res.json()
173-
174-
if (options?.redirect ?? true) {
175-
const url = (data as any).url ?? callbackUrl
176-
window.location.href = url
177-
// If url contains a hash, the browser does not reload the page. We reload manually
178-
if (url.includes('#')) {
179-
window.location.reload()
180-
}
181-
// @ts-expect-error TODO: Fix this
182-
return
183-
}
184-
185-
await __AUTHJS._getSession({ event: 'storage' })
186-
187-
return data as any
188-
}
1+
import { createAuthClient } from 'better-auth/client'
2+
3+
import { API_URL } from '~/constants/env'
4+
5+
export const authClient = createAuthClient({
6+
baseURL: API_URL + '/auth',
7+
fetchOptions: {
8+
credentials: 'include',
9+
},
10+
})
11+
12+
export type AuthSocialProviders =
13+
| 'apple'
14+
| 'discord'
15+
| 'facebook'
16+
| 'github'
17+
| 'google'
18+
| 'microsoft'
19+
| 'spotify'
20+
| 'twitch'
21+
| 'twitter'
22+
| 'dropbox'
23+
| 'linkedin'
24+
| 'gitlab'

0 commit comments

Comments
 (0)