-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support next v13 app dir routes
- Loading branch information
1 parent
be80fec
commit 7e82016
Showing
10 changed files
with
182 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,47 @@ | ||
import type { AuthProvider } from '@/typings/providers.types' | ||
import type { NextAuthRequest } from '@/typings/route.types' | ||
import type { NextApiResponse } from 'next' | ||
import type { NextAuthRequest, NextAuthRequestParams } from '@/typings/route.types' | ||
|
||
import { NextResponse } from 'next/server' | ||
|
||
import logout from '@/api/routes/logout' | ||
import session from '@/api/routes/session' | ||
import signin from '@/api/routes/signin' | ||
import CookieStore from '@/storage/cookie-store' | ||
|
||
type AuthenticationOptions = { | ||
providers: AuthProvider[] | ||
} | ||
|
||
const NextAuth = (options: AuthenticationOptions) => async (req: NextAuthRequest, res: NextApiResponse) => { | ||
const { providers } = options | ||
|
||
if (!req.query.auth) { | ||
return res.status(400).end() | ||
} | ||
|
||
const params = Array.isArray(req.query.auth) ? req.query.auth : [req.query.auth] | ||
const provider = providers.find((p) => p.id === params[1]) | ||
if (provider == null) { | ||
return res.status(400).end() | ||
const NextAuth = | ||
(options: AuthenticationOptions) => | ||
async (request: NextAuthRequest, { params }: NextAuthRequestParams) => { | ||
const { providers } = options | ||
|
||
if (!params.auth) { | ||
return NextResponse.next({ | ||
status: 400, | ||
statusText: `The provider route params 'auth' were not found in the request.`, | ||
}) | ||
} | ||
|
||
const provider = providers.find((p) => p.id === params?.auth?.[1]) | ||
if (provider == null) { | ||
return NextResponse.next({ | ||
status: 400, | ||
statusText: `The provider id '${params?.auth?.[1]}' has not been defined.`, | ||
}) | ||
} | ||
|
||
const redirectUrl = request.nextUrl.searchParams.get('redirect_url') || request.nextUrl.origin | ||
switch (params.auth[0]) { | ||
case 'signin': | ||
return signin(request, { provider, redirect_url: redirectUrl }) | ||
case 'logout': | ||
return logout(request, { provider, redirect_url: redirectUrl }) | ||
case 'session': | ||
return session(request, { provider }) | ||
default: | ||
return NextResponse.next({ status: 400 }) | ||
} | ||
} | ||
|
||
const store = new CookieStore(req, res) | ||
|
||
switch (req.query.auth[0]) { | ||
case 'signin': | ||
return signin(req, res, store, { provider, redirect_url: req.query.redirect_url as string }) | ||
case 'session': | ||
return session(req, res, { provider }) | ||
default: | ||
return res.status(400).end() | ||
} | ||
} | ||
|
||
export default NextAuth |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import type { AuthProvider } from '@/typings/providers.types' | ||
import type { NextAuthRequest } from '@/typings/route.types' | ||
|
||
import { NextResponse } from 'next/server' | ||
|
||
export type LogoutRouteOptions = { | ||
provider: AuthProvider | ||
redirect_url: string | ||
} | ||
|
||
const logout = async (req: NextAuthRequest, options: LogoutRouteOptions): Promise<NextResponse> => { | ||
const { provider } = options | ||
|
||
if (req.method !== 'POST') { | ||
return NextResponse.next({ | ||
status: 400, | ||
statusText: `The logout route expects a POST request but received '${req.method}'.`, | ||
}) | ||
} | ||
|
||
if (!provider) { | ||
return NextResponse.next({ | ||
status: 400, | ||
statusText: `The logout route expects a provider to be included but received '${provider}'.`, | ||
}) | ||
} | ||
|
||
const endpoint = provider.endpoints.logout | ||
if (!endpoint) { | ||
return NextResponse.next({ | ||
status: 400, | ||
statusText: `The logout route expects a logout endpoint to be configured but received '${endpoint}'.`, | ||
}) | ||
} | ||
|
||
const response = await fetch(endpoint, { | ||
method: 'POST', | ||
cache: 'no-cache', | ||
headers: { | ||
Authorization: req.headers.get('authorization') as string, | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
'X-Forwarded-Host': req.headers.get('host') as string, | ||
}, | ||
}) | ||
|
||
if (!response.ok) { | ||
const json = await response.json() | ||
return NextResponse.json(json, { | ||
status: 400, | ||
statusText: `The logout route received a non 200 response and got '${response.status}'.`, | ||
}) | ||
} | ||
|
||
return NextResponse.redirect(options.redirect_url) | ||
} | ||
|
||
export default logout |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,56 @@ | ||
import type { OAuthUserInfoResponse } from '@/typings/oauth.types' | ||
import type { AuthProvider } from '@/typings/providers.types' | ||
import type { NextAuthRequest } from '@/typings/route.types' | ||
import type { NextApiResponse } from 'next' | ||
|
||
import { NextResponse } from 'next/server' | ||
|
||
export type SessionRouteOptions = { | ||
provider: AuthProvider | ||
} | ||
|
||
const session = async ( | ||
req: NextAuthRequest, | ||
res: NextApiResponse, | ||
options: SessionRouteOptions | ||
): Promise<NextApiResponse<any> | any> => { | ||
const session = async (req: NextAuthRequest, options: SessionRouteOptions): Promise<NextResponse> => { | ||
const { provider } = options | ||
|
||
if (req.method === 'POST') { | ||
return res.status(400).end() | ||
return NextResponse.next({ | ||
status: 400, | ||
statusText: `The session route expects a POST request but received '${req.method}'.`, | ||
}) | ||
} | ||
|
||
if (!provider) { | ||
return res.status(400).end() | ||
return NextResponse.next({ | ||
status: 400, | ||
statusText: `The session route expects a provider to be included but received '${provider}'.`, | ||
}) | ||
} | ||
|
||
const endpoint = provider.endpoints.userinfo | ||
if (endpoint == null) { | ||
return res.status(400).end() | ||
if (!endpoint) { | ||
return NextResponse.next({ | ||
status: 400, | ||
statusText: `The session route expects a userinfo endpoint to be configured but received '${endpoint}'.`, | ||
}) | ||
} | ||
|
||
const response = await fetch(endpoint, { | ||
method: 'GET', | ||
cache: 'no-cache', | ||
headers: { | ||
Authorization: req.headers.authorization as string, | ||
'X-Forwarded-Host': req.headers.host as string, | ||
Authorization: req.headers.get('authorization') as string, | ||
'X-Forwarded-Host': req.headers.get('host') as string, | ||
}, | ||
}) | ||
|
||
if (!response.ok) { | ||
return res.status(400).end() | ||
return NextResponse.next({ | ||
status: 400, | ||
statusText: `The session route received a non 200 response and got '${response.status}'.`, | ||
}) | ||
} | ||
|
||
const payload = (await response.json()) as OAuthUserInfoResponse | ||
return res.json(payload) | ||
return NextResponse.json(payload) | ||
} | ||
|
||
export default session |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
export { default as OAuth } from '@/api/authentication' | ||
export { getServerSession } from '@/api/session' | ||
|
||
export { default as SessionContext, SessionProvider } from '@/react/context' | ||
export { default as getSessionServerSideProps } from '@/react/ssr' | ||
|
||
export { default as PasswordProvider } from '@/providers/password' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.