@ -105,6 +105,15 @@ export const SocialLoginButtons = ({ providers }: Props) => {
|
|||||||
Continue with {providers['azure-ad'].name}
|
Continue with {providers['azure-ad'].name}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
{providers?.['custom-oauth'] && (
|
||||||
|
<Button
|
||||||
|
onClick={handleAzureAdClick}
|
||||||
|
isLoading={['loading', 'authenticated'].includes(status)}
|
||||||
|
variant="outline"
|
||||||
|
>
|
||||||
|
Continue with {providers['custom-oauth'].name}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import { Provider } from 'next-auth/providers'
|
|||||||
import { NextApiRequest, NextApiResponse } from 'next'
|
import { NextApiRequest, NextApiResponse } from 'next'
|
||||||
import { CustomAdapter } from './adapter'
|
import { CustomAdapter } from './adapter'
|
||||||
import { User } from 'db'
|
import { User } from 'db'
|
||||||
import { env, isNotEmpty } from 'utils'
|
import { env, getAtPath, isNotEmpty } from 'utils'
|
||||||
import { mockedUser } from '@/features/auth'
|
import { mockedUser } from '@/features/auth'
|
||||||
|
|
||||||
const providers: Provider[] = []
|
const providers: Provider[] = []
|
||||||
@ -97,6 +97,34 @@ if (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isNotEmpty(process.env.CUSTOM_OAUTH_AUTHORIZATION_URL)) {
|
||||||
|
providers.push({
|
||||||
|
id: 'custom-oauth',
|
||||||
|
name: process.env.CUSTOM_OAUTH_NAME ?? 'Custom OAuth',
|
||||||
|
type: 'oauth',
|
||||||
|
authorization: process.env.CUSTOM_OAUTH_AUTHORIZATION_URL,
|
||||||
|
token: process.env.CUSTOM_OAUTH_TOKEN_URL,
|
||||||
|
userinfo: process.env.CUSTOM_OAUTH_USERINFO_URL,
|
||||||
|
profile(profile) {
|
||||||
|
return {
|
||||||
|
id: getAtPath(profile, process.env.CUSTOM_OAUTH_USER_ID_PATH ?? 'id'),
|
||||||
|
name: getAtPath(
|
||||||
|
profile,
|
||||||
|
process.env.CUSTOM_OAUTH_USER_NAME_PATH ?? 'name'
|
||||||
|
),
|
||||||
|
email: getAtPath(
|
||||||
|
profile,
|
||||||
|
process.env.CUSTOM_OAUTH_USER_EMAIL_PATH ?? 'email'
|
||||||
|
),
|
||||||
|
image: getAtPath(
|
||||||
|
profile,
|
||||||
|
process.env.CUSTOM_OAUTH_USER_IMAGE_PATH ?? 'image'
|
||||||
|
),
|
||||||
|
} as User
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
if (
|
if (
|
||||||
req.method === 'GET' &&
|
req.method === 'GET' &&
|
||||||
|
@ -103,6 +103,21 @@ The Authorization callback URL should be `$NEXTAUTH_URL/api/auth/callback/azure-
|
|||||||
| AZURE_AD_CLIENT_SECRET | -- | Application client secret. Can be obtained from Azure Portal. |
|
| AZURE_AD_CLIENT_SECRET | -- | Application client secret. Can be obtained from Azure Portal. |
|
||||||
| AZURE_AD_TENANT_ID | -- | Azure Tenant ID |
|
| AZURE_AD_TENANT_ID | -- | Azure Tenant ID |
|
||||||
|
|
||||||
|
## Custom OAuth Provider (Auth)
|
||||||
|
|
||||||
|
| Parameter | Default | Description |
|
||||||
|
| ------------------------------ | ------------ | ----------------------------------------------------------------------- |
|
||||||
|
| CUSTOM_OAUTH_NAME | Custom OAuth | Provider name. Is displayed in the sign in form. |
|
||||||
|
| CUSTOM_OAUTH_AUTHORIZATION_URL | -- | OAuth autorization URL (i.e. `https://kauth.kakao.com/oauth/authorize`) |
|
||||||
|
| CUSTOM_OAUTH_TOKEN_URL | -- | OAuth token URL (i.e. `https://kauth.kakao.com/oauth/token`) |
|
||||||
|
| CUSTOM_OAUTH_USERINFO_URL | -- | User info URL (i.e. `https://kapi.kakao.com/v2/user/me`) |
|
||||||
|
| CUSTOM_OAUTH_USER_ID_PATH | id | Used to map the id from the user info object |
|
||||||
|
| CUSTOM_OAUTH_USER_NAME_PATH | name | Used to map the name from the user info object |
|
||||||
|
| CUSTOM_OAUTH_USER_EMAIL_PATH | email | Used to map the email from the user info object |
|
||||||
|
| CUSTOM_OAUTH_USER_IMAGE_PATH | image | Used to map the image from the user info object |
|
||||||
|
|
||||||
|
For `*_PATH` parameters, you can use dot notation to access nested properties (i.e. `account.name`).
|
||||||
|
|
||||||
## S3 Storage (Media uploads)
|
## S3 Storage (Media uploads)
|
||||||
|
|
||||||
Used for uploading images, videos, etc... It can be any S3 compatible object storage service (Minio, Digital Oceans Space, AWS S3...)
|
Used for uploading images, videos, etc... It can be any S3 compatible object storage service (Minio, Digital Oceans Space, AWS S3...)
|
||||||
|
@ -303,3 +303,17 @@ export const injectCustomHeadCode = (customHeadCode: string) => {
|
|||||||
document.head.append(noScriptElement)
|
document.head.append(noScriptElement)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getAtPath = <T>(obj: T, path: string): unknown => {
|
||||||
|
if (isNotDefined(obj)) return undefined
|
||||||
|
const pathParts = path.split('.')
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
let current: any = obj
|
||||||
|
for (const part of pathParts) {
|
||||||
|
if (current === undefined) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
current = current[part]
|
||||||
|
}
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user