Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update to use config domain
  • Loading branch information
adam-maj committed Aug 31, 2022
commit 895e42ddecf9c47af20c139adf44875c31be6def
3 changes: 0 additions & 3 deletions packages/auth/.gitignore

This file was deleted.

3 changes: 3 additions & 0 deletions packages/auth/express/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"main": "dist/thirdweb-dev-auth-express.cjs.js"
}
3 changes: 3 additions & 0 deletions packages/auth/next-auth/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"main": "dist/thirdweb-dev-auth-next-auth.cjs.js"
}
3 changes: 3 additions & 0 deletions packages/auth/next/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"main": "dist/thirdweb-dev-auth-next.cjs.js"
}
131 changes: 93 additions & 38 deletions packages/auth/src/next-auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { ThirdwebAuthConfig } from "./types";
import { ThirdwebNextAuthConfig } from "./types";
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import { serialize } from "cookie";
import { NextApiRequest, NextApiResponse } from "next";
import { NextAuthOptions, Session } from "next-auth";
import { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from "next";
import NextAuth, { NextAuthOptions, Session, unstable_getServerSession } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

export function ThirdwebAuth(cfg: ThirdwebAuthConfig) {
export function ThirdwebNextAuth(cfg: ThirdwebNextAuthConfig) {
const sdk = ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet");

const ThirdwebProvider = (req: NextApiRequest, res: NextApiResponse) =>
CredentialsProvider({
function ThirdwebProvider(res: GetServerSidePropsContext["res"]) {
return CredentialsProvider({
name: "ThirdwebAuth",
credentials: {
payload: {
Expand All @@ -22,10 +22,10 @@ export function ThirdwebAuth(cfg: ThirdwebAuthConfig) {
try {
const parsed = JSON.parse(payload);
const token = await sdk.auth.generateAuthToken(
"thirdweb.com",
cfg.domain,
parsed
);
const address = await sdk.auth.authenticate("thirdweb.com", token);
const address = await sdk.auth.authenticate(cfg.domain, token);

// Securely set httpOnly cookie on request to prevent XSS on frontend
// And set path to / to enable thirdweb_auth_token usage on all endpoints
Expand All @@ -45,36 +45,91 @@ export function ThirdwebAuth(cfg: ThirdwebAuthConfig) {
}
},
});
}

const authOptions = (req: NextApiRequest, res: NextApiResponse) =>
({
callbacks: {
async session({ session }) {
const token = req.cookies.thirdweb_auth_token || "";
try {
const address = await sdk.auth.authenticate("thirdweb.com", token);
session.user = { ...session.user, address } as Session["user"];
return session;
} catch {
return session;
}
},
},
events: {
signOut() {
res.setHeader(
"Set-Cookie",
serialize("thirdweb_auth_token", "", {
path: "/",
expires: new Date(Date.now() + 5 * 1000),
})
);
},
},
} as Omit<NextAuthOptions, "providers">);
function nextOptions (
req: GetServerSidePropsContext["req"],
res: GetServerSidePropsContext["res"]
): NextAuthOptions {

return {
ThirdwebProvider,
authOptions,
async function session({ session }: { session: Session }) {
const token = req.cookies.thirdweb_auth_token || "";
try {
const address = await sdk.auth.authenticate(cfg.domain, token);
session.user = { ...session.user, address } as Session["user"];
return session;
} catch {
return session;
}
}

function signOut() {
res.setHeader(
"Set-Cookie",
serialize("thirdweb_auth_token", "", {
path: "/",
expires: new Date(Date.now() + 5 * 1000),
})
);
}

const providers: NextAuthOptions["providers"] = [
...cfg.nextOptions.providers,
ThirdwebProvider(res),
]

const configSession = cfg.nextOptions.callbacks?.session
const callbacks: NextAuthOptions["callbacks"] = {
...cfg.nextOptions.callbacks,
session: configSession
? async (params) => {
params.session = await session(params);
return configSession(params);
}
: session
};

const configSignOut = cfg.nextOptions.events?.signOut
const events: NextAuthOptions["events"] = {
...cfg.nextOptions.events,
signOut: configSignOut
? async (params) => {
signOut();
return configSignOut(params);
}
: signOut
};

return {
...cfg.nextOptions,
providers,
callbacks,
events,
};
};
}

async function getUser(
...args:
| [NextApiRequest, NextApiResponse]
| [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]]
) {
return unstable_getServerSession(args[0], args[1], nextOptions(args[0], args[1]));
}

function NextAuthHandler(
...args: [] | [NextApiRequest, NextApiResponse]
) {
if (args.length === 0) {
return (req: NextApiRequest, res: NextApiResponse) => {
return NextAuth(req, res, nextOptions(req, res));
}
}

return NextAuth(args[0], args[1], nextOptions(args[0], args[1]));
}

return {
NextAuthHandler,
getUser
}
}
7 changes: 5 additions & 2 deletions packages/auth/src/next-auth/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export type ThirdwebAuthConfig = {
import { NextAuthOptions } from "next-auth";

export type ThirdwebNextAuthConfig = {
privateKey: string;
domain: string;
};
nextOptions: NextAuthOptions;
}
2 changes: 1 addition & 1 deletion turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
]
},
"auth#build": {
"outputs": ["dist/**", "express/**", "next/**"]
"outputs": ["dist/**", "express/**", "next/**", "next-auth/**"]
},
"test": {
"outputs": [],
Expand Down