-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
Copy pathclient.ts
175 lines (157 loc) · 5.13 KB
/
client.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import { base } from "$app/paths"
import type { ProviderId } from "@auth/core/providers"
export interface SignInOptions<Redirect extends boolean = true>
extends Record<string, unknown> {
/** @deprecated Use `redirectTo` instead. */
callbackUrl?: string
/**
* Specify where the user should be redirected to after a successful signin.
*
* By default, it is the page the sign-in was initiated from.
*/
redirectTo?: string
/**
* You might want to deal with the signin response on the same page, instead of redirecting to another page.
* For example, if an error occurs (like wrong credentials given by the user), you might want to show an inline error message on the input field.
*
* For this purpose, you can set this to option `redirect: false`.
*/
redirect?: Redirect
}
export interface SignInResponse {
error: string | undefined
code: string | undefined
status: number
ok: boolean
url: string | null
}
export interface SignOutParams<Redirect extends boolean = true> {
/** @deprecated Use `redirectTo` instead. */
callbackUrl?: string
/**
* If you pass `redirect: false`, the page will not reload.
* The session will be deleted, and `useSession` is notified, so any indication about the user will be shown as logged out automatically.
* It can give a very nice experience for the user.
*/
redirectTo?: string
/** [Documentation](https://next-auth.js.org/getting-started/client#using-the-redirect-false-option-1 */
redirect?: Redirect
}
/** Match `inputType` of `new URLSearchParams(inputType)` */
export type SignInAuthorizationParams =
| string
| string[][]
| Record<string, string>
| URLSearchParams
/**
* Client-side method to initiate a signin flow
* or send the user to the signin page listing all possible providers.
*
* [Documentation](https://authjs.dev/reference/sveltekit/client#signin)
*/
/**
* Initiates a signin flow or sends the user to the signin page listing all possible providers.
* Handles CSRF protection.
*
* @note This method can only be used from Client Components ("use client" or Pages Router).
* For Server Actions, use the `signIn` method imported from the `auth` config.
*/
export async function signIn(
provider?: ProviderId,
options?: SignInOptions<true>,
authorizationParams?: SignInAuthorizationParams
): Promise<void>
export async function signIn(
provider?: ProviderId,
options?: SignInOptions<false>,
authorizationParams?: SignInAuthorizationParams
): Promise<SignInResponse>
export async function signIn<Redirect extends boolean = true>(
provider?: ProviderId,
options?: SignInOptions<Redirect>,
authorizationParams?: SignInAuthorizationParams
): Promise<SignInResponse | void> {
const { callbackUrl, ...rest } = options ?? {}
const {
redirect = true,
redirectTo = callbackUrl ?? window.location.href,
...signInParams
} = rest
const baseUrl = `${base}/auth`
const signInUrl = `${baseUrl}/${
provider === "credentials" ? "callback" : "signin"
}/${provider}`
const res = await fetch(
`${signInUrl}?${new URLSearchParams(authorizationParams)}`,
{
method: "post",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Auth-Return-Redirect": "1",
},
body: new URLSearchParams({
...signInParams,
callbackUrl: redirectTo,
}),
}
)
const data = await res.json()
if (redirect) {
const url = data.url ?? redirectTo
window.location.href = url
// If url contains a hash, the browser does not reload the page. We reload manually
if (url.includes("#")) window.location.reload()
return
}
const error = new URL(data.url).searchParams.get("error") ?? undefined
const code = new URL(data.url).searchParams.get("code") ?? undefined
return {
error,
code,
status: res.status,
ok: res.ok,
url: error ? null : data.url,
}
}
export interface SignOutResponse {
url: string
}
/**
* Initiate a signout, by destroying the current session.
* Handles CSRF protection.
*
* @note This method can only be used from Client Components ("use client" or Pages Router).
* For Server Actions, use the `signOut` method imported from the `auth` config.
*/
export async function signOut(options?: SignOutParams<true>): Promise<void>
export async function signOut(
options?: SignOutParams<false>
): Promise<SignOutResponse>
export async function signOut<R extends boolean = true>(
options?: SignOutParams<R>
): Promise<SignOutResponse | void> {
const {
redirect = true,
redirectTo = options?.callbackUrl ?? window.location.href,
} = options ?? {}
const baseUrl = `${base}/auth`
const res = await fetch(`${baseUrl}/signout`, {
method: "post",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Auth-Return-Redirect": "1",
},
body: new URLSearchParams({
callbackUrl: redirectTo,
}),
})
const data = await res.json()
if (redirect) {
const url = data.url ?? redirectTo
window.location.href = url
// If url contains a hash, the browser does not reload the page. We reload manually
if (url.includes("#")) window.location.reload()
return
}
return data
}