mirror of
https://github.com/wassname/Open-Assistant.git
synced 2026-07-05 17:30:48 +08:00
Merge pull request #441 from LAION-AI/236-admin-role
Creating a role field for Users #236
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
ADMIN_USERS = "credentials:admin,discord:root,email:admin@example.com"
|
||||
|
||||
# The database created by running the jobs in /scripts/frontend-development/docker-compose.yaml
|
||||
DATABASE_URL=postgres://postgres:postgres@localhost:5433/oasst_web
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ model User {
|
||||
email String? @unique
|
||||
emailVerified DateTime?
|
||||
image String?
|
||||
role String @default("general")
|
||||
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
|
||||
@@ -59,6 +59,17 @@ if (boolean(process.env.DEBUG_LOGIN) || process.env.NODE_ENV === "development")
|
||||
);
|
||||
}
|
||||
|
||||
// Create a map of provider types to a set of admin user identifiers based on
|
||||
// the environment variables. We assume the list is separated by ',' and each
|
||||
// entry is separated by ':'.
|
||||
const adminUserMap = process.env.ADMIN_USERS.split(",").reduce((result, entry) => {
|
||||
const [authType, id] = entry.split(":");
|
||||
const s = result.get(authType) || new Set();
|
||||
s.add(id);
|
||||
result.set(authType, s);
|
||||
return result;
|
||||
}, new Map());
|
||||
|
||||
export const authOptions: AuthOptions = {
|
||||
// Ensure we can store user data in a database.
|
||||
adapter: PrismaAdapter(prisma),
|
||||
@@ -68,6 +79,56 @@ export const authOptions: AuthOptions = {
|
||||
verifyRequest: "/auth/verify",
|
||||
// error: "/auth/error", -Will be used later
|
||||
},
|
||||
callbacks: {
|
||||
/**
|
||||
* Ensure we propagate the user's role when creating the session from the
|
||||
* token.
|
||||
*/
|
||||
async session({ session, token }) {
|
||||
session.user.role = token.role;
|
||||
return session;
|
||||
},
|
||||
/**
|
||||
* When creating a token, fetch the user's role and inject it in the token.
|
||||
* This let's use forward the role to the session object.
|
||||
*/
|
||||
async jwt({ token }) {
|
||||
const { role } = await prisma.user.findUnique({
|
||||
where: { id: token.sub },
|
||||
select: { role: true },
|
||||
});
|
||||
token.role = role;
|
||||
return token;
|
||||
},
|
||||
},
|
||||
events: {
|
||||
/**
|
||||
* Update the user's role after they have successfully signed in
|
||||
*/
|
||||
async signIn({ user, account }) {
|
||||
// Get the admin list for the user's auth type.
|
||||
const adminForAccountType = adminUserMap.get(account.provider);
|
||||
|
||||
// Return early if there's no admin list.
|
||||
if (!adminForAccountType) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(#236): Reduce the number of times we update the role field.
|
||||
|
||||
// Update the database if the user is an admin.
|
||||
if (adminForAccountType.has(account.providerAccountId)) {
|
||||
await prisma.user.update({
|
||||
data: {
|
||||
role: "admin",
|
||||
},
|
||||
where: {
|
||||
id: user.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
session: {
|
||||
strategy: "jwt",
|
||||
},
|
||||
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
import NextAuth, { DefaultSession } from "next-auth";
|
||||
import { JWT } from "next-auth/jwt";
|
||||
|
||||
declare module "next-auth" {
|
||||
interface Session {
|
||||
user: {
|
||||
/** The user's role. */
|
||||
role: string;
|
||||
} & DefaultSession["user"];
|
||||
}
|
||||
}
|
||||
|
||||
declare module "next-auth/jwt" {
|
||||
interface JWT {
|
||||
/** The user's role. */
|
||||
role?: string;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user