-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
feat(providers): Add Epic Games provider #12944
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/** | ||
* <div class="provider" style={{backgroundColor: "#000", display: "flex", justifyContent: "space-between", color: "#fff", padding: 16}}> | ||
* <span>Built-in <b>Epic Games</b> integration.</span> | ||
* <a href="https://store.epicgames.com/"> | ||
* <img style={{display: "block"}} src="https://authjs.dev/img/providers/epicgames.svg" height="48" width="48"/> | ||
* </a> | ||
* </div> | ||
* | ||
* @module providers/epicgames | ||
*/ | ||
|
||
/** | ||
* @provider EpicGames | ||
* | ||
* Epic Games OAuth Provider for Auth.js | ||
* | ||
* This provider uses OAuth 2.0 to authenticate users with their Epic Games account. | ||
* | ||
* @see [Epic Games OAuth Documentation] | ||
* (https://dev.epicgames.com/docs/services/en-US/EpicAccountServices) | ||
* @see [Auth.js OAuth Providers Guide](https://authjs.dev/guides/configuring-oauth-providers) | ||
* | ||
* @example | ||
* ```ts | ||
* import EpicGamesProvider from "next-auth/providers/epicgames" | ||
* | ||
* export default NextAuth({ | ||
* providers: [ | ||
* EpicGamesProvider({ | ||
* clientId: process.env.EPIC_CLIENT_ID, | ||
* clientSecret: process.env.EPIC_CLIENT_SECRET, | ||
* }) | ||
* ] | ||
* }) | ||
* ``` | ||
* | ||
* ### Environment Variables | ||
* | ||
* - `EPIC_CLIENT_ID` | ||
* - `EPIC_CLIENT_SECRET` | ||
* | ||
* ### Profile Response | ||
* | ||
* The Epic Games profile has the following structure: | ||
* | ||
* ```json | ||
* { | ||
* "sub": "user_id_123", | ||
* "preferred_username": "EpicUser123" | ||
* } | ||
* ``` | ||
*/ | ||
|
||
import type { OAuthConfig, OAuthUserConfig } from "./index.js" | ||
|
||
/** | ||
* The shape of the user object returned by Epic Games when requesting user info. | ||
* Properties must be adapted based on the exact data the client decides to receive from the Epic Games API. | ||
*/ | ||
export interface EpicGamesProfile { | ||
sub: string | ||
preferred_username?: string | ||
// preferred_language?: string; | ||
} | ||
|
||
/** | ||
* Configure the Epic Games OAuth provider. | ||
* | ||
* @param {OAuthUserConfig<EpicGamesProfile>} options - User configuration for the Epic Games provider | ||
* @returns {OAuthConfig<EpicGamesProfile>} - An object conforming to the Auth.js OAuthConfig interface | ||
* | ||
* @example | ||
* ```ts | ||
* import EpicGamesProvider from "next-auth/providers/epicgames" | ||
* // ... | ||
* providers: [ | ||
* EpicGamesProvider({ | ||
* clientId: process.env.EPIC_CLIENT_ID, | ||
* clientSecret: process.env.EPIC_CLIENT_SECRET, | ||
* }) | ||
* ] | ||
* ``` | ||
*/ | ||
export default function EpicGamesProvider<P extends EpicGamesProfile>( | ||
options: OAuthUserConfig<P> | ||
): OAuthConfig<P> { | ||
return { | ||
id: "epicgames", | ||
name: "Epic Games", | ||
type: "oauth", | ||
authorization: { | ||
url: "https://www.epicgames.com/id/authorize", | ||
params: { | ||
scope: "profile friends_list country", | ||
response_type: "code", | ||
}, | ||
}, | ||
|
||
token: { | ||
url: "https://api.epicgames.dev/epic/oauth/v2/token", | ||
async request(context) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can simplify this by utilising the property |
||
const basicAuth = Buffer.from( | ||
`${context.provider.clientId}:${context.provider.clientSecret}` | ||
).toString("base64") | ||
|
||
const res = await fetch( | ||
"https://api.epicgames.dev/epic/oauth/v2/token", | ||
{ | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/x-www-form-urlencoded", | ||
Authorization: `Basic ${basicAuth}`, | ||
}, | ||
body: new URLSearchParams({ | ||
grant_type: "authorization_code", | ||
code: context.params.code!, | ||
redirect_uri: context.provider.callbackUrl, | ||
}), | ||
} | ||
) | ||
|
||
const tokens = await res.json() | ||
if (!res.ok) throw new Error(JSON.stringify(tokens)) | ||
|
||
return { tokens } | ||
}, | ||
}, | ||
|
||
userinfo: "https://api.epicgames.dev/epic/oauth/v2/userInfo", | ||
|
||
profile(profile: P) { | ||
return { | ||
id: profile.sub, | ||
name: profile.preferred_username ?? profile.sub, | ||
} | ||
}, | ||
|
||
checks: ["state"], | ||
clientId: options.clientId, | ||
clientSecret: options.clientSecret, | ||
Comment on lines
+139
to
+140
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no needed to be explicit define these |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for default scope, let's not include these