first version which seems to run
This commit is contained in:
124
pages/api/tina/[...routes].ts
Normal file
124
pages/api/tina/[...routes].ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import {
|
||||
TinaNodeBackend,
|
||||
LocalBackendAuthProvider,
|
||||
} from "@tinacms/datalayer";
|
||||
import NextAuth from "next-auth";
|
||||
import CredentialsProvider from "next-auth/providers/credentials";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
|
||||
import databaseClient from "../../../tina/__generated__/databaseClient";
|
||||
|
||||
const isLocal = process.env.TINA_PUBLIC_IS_LOCAL === "true";
|
||||
|
||||
const TINA_CREDENTIALS_PROVIDER_NAME = "TinaCredentials";
|
||||
|
||||
const authenticate = async (
|
||||
dbClient: typeof databaseClient,
|
||||
username: string,
|
||||
password: string
|
||||
) => {
|
||||
try {
|
||||
const result = await dbClient.authenticate({ username, password });
|
||||
return result.data?.authenticate || null;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const authOptions = {
|
||||
callbacks: {
|
||||
jwt: async ({ token: jwt, account }: any) => {
|
||||
if (account) {
|
||||
try {
|
||||
if (jwt?.sub) {
|
||||
const result = await databaseClient.authorize({ sub: jwt.sub });
|
||||
jwt.role = result.data?.authorize ? "user" : "guest";
|
||||
jwt.passwordChangeRequired =
|
||||
result.data?.authorize?._password?.passwordChangeRequired ||
|
||||
false;
|
||||
}
|
||||
} catch {
|
||||
// ignore auth errors
|
||||
}
|
||||
if (jwt.role === undefined) {
|
||||
jwt.role = "guest";
|
||||
}
|
||||
}
|
||||
return jwt;
|
||||
},
|
||||
session: async ({ session, token: jwt }: any) => {
|
||||
session.user.role = jwt.role;
|
||||
session.user.passwordChangeRequired = jwt.passwordChangeRequired;
|
||||
session.user.sub = jwt.sub;
|
||||
return session;
|
||||
},
|
||||
},
|
||||
session: { strategy: "jwt" as const },
|
||||
secret: process.env.NEXTAUTH_SECRET as string,
|
||||
providers: [
|
||||
CredentialsProvider({
|
||||
name: TINA_CREDENTIALS_PROVIDER_NAME,
|
||||
credentials: {
|
||||
username: { label: "Username", type: "text" },
|
||||
password: { label: "Password", type: "password" },
|
||||
},
|
||||
authorize: async (credentials: any) =>
|
||||
authenticate(databaseClient, credentials.username, credentials.password),
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
const handler = TinaNodeBackend({
|
||||
authProvider: isLocal
|
||||
? LocalBackendAuthProvider()
|
||||
: {
|
||||
initialize: async () => {},
|
||||
isAuthorized: async (req: any, res: any) => {
|
||||
const session = await getServerSession(req, res, authOptions);
|
||||
if (!req.session) {
|
||||
Object.defineProperty(req, "session", {
|
||||
value: session,
|
||||
writable: false,
|
||||
});
|
||||
}
|
||||
if (!(session as any)?.user) {
|
||||
return {
|
||||
errorCode: 401,
|
||||
errorMessage: "Unauthorized",
|
||||
isAuthorized: false,
|
||||
};
|
||||
}
|
||||
if ((session as any)?.user?.role !== "user") {
|
||||
return {
|
||||
errorCode: 403,
|
||||
errorMessage: "Forbidden",
|
||||
isAuthorized: false,
|
||||
};
|
||||
}
|
||||
return { isAuthorized: true };
|
||||
},
|
||||
extraRoutes: {
|
||||
auth: {
|
||||
secure: false,
|
||||
handler: async (req: any, res: any, opts: any) => {
|
||||
const url = new URL(
|
||||
req.url,
|
||||
`http://${req.headers?.host || "localhost"}`
|
||||
);
|
||||
const authSubRoutes = url.pathname
|
||||
?.replace(`${opts.basePath}auth/`, "")
|
||||
?.split("/");
|
||||
req.query.nextauth = authSubRoutes;
|
||||
await NextAuth(authOptions)(req, res);
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
databaseClient,
|
||||
});
|
||||
|
||||
export default (req: any, res: any) => {
|
||||
return handler(req, res);
|
||||
};
|
||||
|
||||
export { authOptions };
|
||||
Reference in New Issue
Block a user