-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: Add Facebook oAuth provider * feat: add Facebook provider to README * fix: lint README * fix: typo in README * fix: lint app.vue * fix: typo in README * chore: use name for playground --------- Co-authored-by: Sébastien Chopin <[email protected]>
- Loading branch information
1 parent
b74d47b
commit 777d8b2
Showing
8 changed files
with
199 additions
and
31 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
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
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,12 @@ | ||
export default oauth.facebookEventHandler({ | ||
async onSuccess(event, { user }) { | ||
await setUserSession(event, { | ||
user: { | ||
facebook: user.name, | ||
}, | ||
loggedInAt: Date.now(), | ||
}) | ||
|
||
return sendRedirect(event, '/') | ||
}, | ||
}) |
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,138 @@ | ||
import type { H3Event } from 'h3' | ||
import { | ||
eventHandler, | ||
createError, | ||
getQuery, | ||
getRequestURL, | ||
sendRedirect, | ||
} from 'h3' | ||
import { ofetch } from 'ofetch' | ||
import { withQuery } from 'ufo' | ||
import { defu } from 'defu' | ||
import { useRuntimeConfig } from '#imports' | ||
import type { OAuthConfig } from '#auth-utils' | ||
|
||
export interface OAuthFacebookConfig { | ||
/** | ||
* Facebook OAuth Client ID | ||
* @default process.env.NUXT_OAUTH_FACEBOOK_CLIENT_ID | ||
*/ | ||
clientId?: string | ||
/** | ||
* Facebook OAuth Client Secret | ||
* @default process.env.NUXT_OAUTH_FACEBOOK_CLIENT_SECRET | ||
*/ | ||
clientSecret?: string | ||
/** | ||
* Facebook OAuth Scope | ||
* @default [] | ||
* @see https://developers.facebook.com/docs/permissions | ||
* @example [ 'email' ], | ||
*/ | ||
scope?: string[] | ||
|
||
/** | ||
* Facebook OAuth Authorization URL | ||
* @default 'https://www.facebook.com/v19.0/dialog/oauth' | ||
*/ | ||
authorizationURL?: string | ||
|
||
/** | ||
* Facebook OAuth Token URL | ||
* @default 'https://graph.facebook.com/v19.0/oauth/access_token' | ||
*/ | ||
tokenURL?: string | ||
|
||
/** | ||
* Extra authorization parameters to provide to the authorization URL | ||
* @see https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow/ | ||
*/ | ||
authorizationParams?: Record<string, string> | ||
} | ||
|
||
export function facebookEventHandler({ | ||
config, | ||
onSuccess, | ||
onError, | ||
}: OAuthConfig<OAuthFacebookConfig>) { | ||
return eventHandler(async (event: H3Event) => { | ||
config = defu(config, useRuntimeConfig(event).oauth?.facebook, { | ||
authorizationURL: 'https://www.facebook.com/v19.0/dialog/oauth', | ||
tokenURL: 'https://graph.facebook.com/v19.0/oauth/access_token', | ||
authorizationParams: {}, | ||
}) as OAuthFacebookConfig | ||
const query = getQuery(event) | ||
|
||
if (query.error) { | ||
const error = createError({ | ||
statusCode: 401, | ||
message: `Facebook login failed: ${query.error || 'Unknown error'}`, | ||
data: query, | ||
}) | ||
if (!onError) throw error | ||
return onError(event, error) | ||
} | ||
|
||
if (!config.clientId) { | ||
const error = createError({ | ||
statusCode: 500, | ||
message: | ||
'Missing NUXT_OAUTH_FACEBOOK_CLIENT_ID or NUXT_OAUTH_FACEBOOK_CLIENT_SECRET env variables.', | ||
}) | ||
if (!onError) throw error | ||
return onError(event, error) | ||
} | ||
|
||
const redirectUrl = getRequestURL(event).href | ||
|
||
if (!query.code) { | ||
config.scope = config.scope || [] | ||
// Redirect to Facebook Oauth page | ||
return sendRedirect( | ||
event, | ||
withQuery(config.authorizationURL as string, { | ||
client_id: config.clientId, | ||
redirect_uri: redirectUrl, | ||
scope: config.scope.join(' '), | ||
}), | ||
) | ||
} | ||
|
||
// TODO: improve typing | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const tokens: any = await $fetch(config.tokenURL as string, { | ||
method: 'POST', | ||
body: { | ||
client_id: config.clientId, | ||
client_secret: config.clientSecret, | ||
redirect_uri: redirectUrl, | ||
code: query.code, | ||
}, | ||
}) | ||
if (tokens.error) { | ||
const error = createError({ | ||
statusCode: 401, | ||
message: `Facebook login failed: ${tokens.error || 'Unknown error'}`, | ||
data: tokens, | ||
}) | ||
if (!onError) throw error | ||
return onError(event, error) | ||
} | ||
|
||
const accessToken = tokens.access_token | ||
// TODO: improve typing | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const user: any = await ofetch( | ||
`https://graph.facebook.com/v19.0/me?fields=id,name&access_token=${accessToken}`, | ||
) | ||
|
||
if (!user) { | ||
throw new Error('Facebook login failed: no user found') | ||
} | ||
|
||
return onSuccess(event, { | ||
user, | ||
tokens, | ||
}) | ||
}) | ||
} |
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