Any chance we can have some kind of documentation on the specifications for oauth2 with xenforo especially on what parameters are being required and sent?
thats what i have right now but i had no luck getting it to work on my nextjs demo app, but i have to say i am pretty new and not an expert here.
thats what i have right now but i had no luck getting it to work on my nextjs demo app, but i have to say i am pretty new and not an expert here.
JavaScript:
// /app/api/auth/auth-options.ts
import type { NextAuthOptions, Session } from "next-auth";
import { JWT } from "next-auth/jwt";
declare module "next-auth" {
interface Session {
accessToken?: string;
user: {
id: string;
name?: string | null;
email?: string | null;
image?: string | null;
}
}
}
export const authOptions: NextAuthOptions = {
providers: [
{
id: "xenforo",
name: "Xenforo",
type: "oauth",
authorization: {
url: "https://www.myxenforourl.de/oauth2/authorize",
params: {
scope: "alert:read alert:write profile_post:read profile_post:write user:read user:write",
response_type: "code",
code_challenge_method: "S256",
},
},
token: {
url: "https://www.myxenforourl.de/api/oauth2/token",
async request({ client, params, checks, provider }) {
const response = await client.oauthCallback(
provider.callbackUrl,
params,
checks,
{
exchangeBody: {
client_id: provider.clientId,
grant_type: "authorization_code",
}
}
)
console.log("Token response:", response);
return { tokens: response }
},
},
userinfo: "https://www.myxenforourl.de/api/oauth2/userinfo",
clientId: process.env.XENFORO_CLIENT_ID,
clientSecret: process.env.XENFORO_CLIENT_SECRET,
checks: ["pkce", "state"],
profile(profile) {
console.log("Raw profile:", profile);
return {
id: profile.sub,
name: profile.name || profile.username,
email: profile.email,
image: profile.avatar_url,
};
},
},
],
debug: true,
callbacks: {
async jwt({ token, account }) {
console.log("JWT callback - token:", token, "account:", account);
if (account?.access_token) {
token.accessToken = account.access_token;
}
return token;
},
async session({ session, token }: { session: Session; token: JWT }) {
console.log("Session callback - session:", session, "token:", token);
return {
...session,
accessToken: token.accessToken as string,
};
},
},
pages: {
signIn: "/signin",
},
events: {
async signIn(message) { console.log("Successful sign in", message) },
async signOut(message) { console.log("Sign out", message) },
},
};