-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
/
actions.ts
139 lines (114 loc) · 4.32 KB
/
actions.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
import { Auth, raw, skipCSRFCheck, createActionURL } from "@auth/core"
import { headers as nextHeaders, cookies } from "next/headers.js"
import { redirect } from "next/navigation.js"
import type { NextAuthConfig } from "./index.js"
import type { NextAuthResult, Session } from "../index.js"
import type { ProviderType } from "@auth/core/providers"
type SignInParams = Parameters<NextAuthResult["signIn"]>
export async function signIn(
provider: SignInParams[0],
options: SignInParams[1] = {},
authorizationParams: SignInParams[2],
config: NextAuthConfig
) {
const headers = new Headers(nextHeaders())
const {
redirect: shouldRedirect = true,
redirectTo,
...rest
} = options instanceof FormData ? Object.fromEntries(options) : options
const callbackUrl = redirectTo?.toString() ?? headers.get("Referer") ?? "/"
const signInURL = createActionURL(
"signin",
// @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
headers.get("x-forwarded-proto"),
headers,
process.env,
config.basePath
)
if (!provider) {
signInURL.searchParams.append("callbackUrl", callbackUrl)
if (shouldRedirect) redirect(signInURL.toString())
return signInURL.toString()
}
let url = `${signInURL}/${provider}?${new URLSearchParams(
authorizationParams
)}`
let foundProvider: { id?: SignInParams[0]; type?: ProviderType } = {}
for (const providerConfig of config.providers) {
const { options, ...defaults } =
typeof providerConfig === "function" ? providerConfig() : providerConfig
const id = (options?.id as string | undefined) ?? defaults.id
if (id === provider) {
foundProvider = {
id,
type: (options?.type as ProviderType | undefined) ?? defaults.type,
}
break
}
}
if (!foundProvider.id) {
const url = `${signInURL}?${new URLSearchParams({ callbackUrl })}`
if (shouldRedirect) redirect(url)
return url
}
if (foundProvider.type === "credentials") {
url = url.replace("signin", "callback")
}
headers.set("Content-Type", "application/x-www-form-urlencoded")
const body = new URLSearchParams({ ...rest, callbackUrl })
const req = new Request(url, { method: "POST", headers, body })
const res = await Auth(req, { ...config, raw, skipCSRFCheck })
for (const c of res?.cookies ?? []) cookies().set(c.name, c.value, c.options)
const responseUrl =
res instanceof Response ? res.headers.get("Location") : res.redirect
// NOTE: if for some unexpected reason the responseUrl is not set,
// we redirect to the original url
const redirectUrl = responseUrl ?? url
if (shouldRedirect) return redirect(redirectUrl)
return redirectUrl as any
}
type SignOutParams = Parameters<NextAuthResult["signOut"]>
export async function signOut(
options: SignOutParams[0],
config: NextAuthConfig
) {
const headers = new Headers(nextHeaders())
headers.set("Content-Type", "application/x-www-form-urlencoded")
const url = createActionURL(
"signout",
// @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
headers.get("x-forwarded-proto"),
headers,
process.env,
config.basePath
)
const callbackUrl = options?.redirectTo ?? headers.get("Referer") ?? "/"
const body = new URLSearchParams({ callbackUrl })
const req = new Request(url, { method: "POST", headers, body })
const res = await Auth(req, { ...config, raw, skipCSRFCheck })
for (const c of res?.cookies ?? []) cookies().set(c.name, c.value, c.options)
if (options?.redirect ?? true) return redirect(res.redirect!)
return res as any
}
type UpdateParams = Parameters<NextAuthResult["unstable_update"]>
export async function update(
data: UpdateParams[0],
config: NextAuthConfig
): Promise<Session | null> {
const headers = new Headers(nextHeaders())
headers.set("Content-Type", "application/json")
const url = createActionURL(
"session",
// @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
headers.get("x-forwarded-proto"),
headers,
process.env,
config.basePath
)
const body = JSON.stringify({ data })
const req = new Request(url, { method: "POST", headers, body })
const res: any = await Auth(req, { ...config, raw, skipCSRFCheck })
for (const c of res?.cookies ?? []) cookies().set(c.name, c.value, c.options)
return res.body
}