mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
Compare commits
6 Commits
@auth/soli
...
fix/confor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
342202db87 | ||
|
|
49cbf7431b | ||
|
|
c7705eec35 | ||
|
|
2d493d70e8 | ||
|
|
ddbb4b0e51 | ||
|
|
d785c5984f |
@@ -104,7 +104,7 @@ export async function handleOAuth(
|
||||
resCookies.push(nonce.cookie)
|
||||
}
|
||||
|
||||
const codeGrantResponse = await o.authorizationCodeGrantRequest(
|
||||
let codeGrantResponse = await o.authorizationCodeGrantRequest(
|
||||
as,
|
||||
client,
|
||||
parameters,
|
||||
@@ -112,6 +112,12 @@ export async function handleOAuth(
|
||||
codeVerifier?.codeVerifier ?? "auth" // TODO: review fallback code verifier
|
||||
)
|
||||
|
||||
if (provider.token?.conform) {
|
||||
codeGrantResponse =
|
||||
(await provider.token.conform(codeGrantResponse.clone())) ??
|
||||
codeGrantResponse
|
||||
}
|
||||
|
||||
let challenges: o.WWWAuthenticateChallenge[] | undefined
|
||||
if ((challenges = o.parseWwwAuthenticateChallenges(codeGrantResponse))) {
|
||||
for (const challenge of challenges) {
|
||||
|
||||
@@ -96,6 +96,9 @@ function normalizeEndpoint(
|
||||
// NOTE: This need to be checked when constructing the URL
|
||||
// for the authorization, token and userinfo endpoints.
|
||||
const url = new URL(e?.url ?? "https://authjs.dev")
|
||||
for (const k in e?.params) url.searchParams.set(k, e?.params[k])
|
||||
return { url, request: e?.request }
|
||||
for (const k in e?.params) {
|
||||
if (e?.params && k === "claims") e.params[k] = JSON.stringify(e.params[k])
|
||||
url.searchParams.set(k, e?.params[k])
|
||||
}
|
||||
return { url, request: e?.request, conform: e?.conform }
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ interface AdvancedEndpointHandler<P extends UrlParams, C, R> {
|
||||
* You should **try to avoid using advanced options** unless you are very comfortable using them.
|
||||
*/
|
||||
request?: EndpointRequest<C, R, P>
|
||||
/** @internal */
|
||||
conform?: (response: Response) => Awaitable<Response | undefined>
|
||||
}
|
||||
|
||||
/** Either an URL (containing all the parameters) or an object with more granular control. */
|
||||
@@ -184,7 +186,11 @@ export type OAuthConfigInternal<Profile> = Omit<
|
||||
OAuthEndpointType
|
||||
> & {
|
||||
authorization?: { url: URL }
|
||||
token?: { url: URL; request?: TokenEndpointHandler["request"] }
|
||||
token?: {
|
||||
url: URL
|
||||
request?: TokenEndpointHandler["request"]
|
||||
conform?: TokenEndpointHandler["conform"]
|
||||
}
|
||||
userinfo?: { url: URL; request?: UserinfoEndpointHandler["request"] }
|
||||
} & Pick<Required<OAuthConfig<Profile>>, "clientId" | "checks" | "profile">
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { OAuthConfig, OAuthUserConfig } from "./index.js"
|
||||
import type { OIDCConfig, OIDCUserConfig } from "./index.js"
|
||||
|
||||
export interface TwitchProfile extends Record<string, any> {
|
||||
sub: string
|
||||
@@ -7,26 +7,52 @@ export interface TwitchProfile extends Record<string, any> {
|
||||
picture: string
|
||||
}
|
||||
|
||||
export default function Twitch<P extends TwitchProfile>(
|
||||
options: OAuthUserConfig<P>
|
||||
): OAuthConfig<P> {
|
||||
export default function Twitch(
|
||||
config: OIDCUserConfig<TwitchProfile>
|
||||
): OIDCConfig<TwitchProfile> {
|
||||
return {
|
||||
issuer: "https://id.twitch.tv/oauth2",
|
||||
id: "twitch",
|
||||
name: "Twitch",
|
||||
type: "oidc",
|
||||
client: { token_endpoint_auth_method: "client_secret_post" },
|
||||
authorization: {
|
||||
params: {
|
||||
scope: "openid user:read:email",
|
||||
claims: {
|
||||
id_token: {
|
||||
email: null,
|
||||
picture: null,
|
||||
preferred_username: null,
|
||||
},
|
||||
id_token: { email: null, picture: null, preferred_username: null },
|
||||
},
|
||||
},
|
||||
},
|
||||
token: {
|
||||
async conform(response) {
|
||||
const body = await response.json()
|
||||
if (response.ok) {
|
||||
if (typeof body.scope === "string") {
|
||||
console.warn(
|
||||
"'scope' is a string. Redundant workaround, please open an issue."
|
||||
)
|
||||
} else if (Array.isArray(body.scope)) {
|
||||
body.scope = body.scope.join(" ")
|
||||
return new Response(JSON.stringify(body), response)
|
||||
} else if ("scope" in body) {
|
||||
delete body.scope
|
||||
return new Response(JSON.stringify(body), response)
|
||||
}
|
||||
} else {
|
||||
const { message: error_description, error } = body
|
||||
if (typeof error !== "string") {
|
||||
return new Response(
|
||||
JSON.stringify({ error: "invalid_request", error_description }),
|
||||
response
|
||||
)
|
||||
}
|
||||
console.warn(
|
||||
"Response has 'error'. Redundant workaround, please open an issue."
|
||||
)
|
||||
}
|
||||
},
|
||||
},
|
||||
style: {
|
||||
logo: "/twitch.svg",
|
||||
logoDark: "/twitch-dark.svg",
|
||||
@@ -35,6 +61,6 @@ export default function Twitch<P extends TwitchProfile>(
|
||||
bgDark: "#65459B",
|
||||
textDark: "#fff",
|
||||
},
|
||||
options,
|
||||
options: config,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user