Как сделать проверку на то что пользователь существует в nextjs при использование middleware?
Для аутентификации использую [email protected], вот такая конструкция,
middleware.js
import NextAuth from "next-auth";
import { authConfig } from "@/app/authConfig";
export default NextAuth(authConfig).auth;
export const config = {
matcher: ['/((?!api|static|.*\\..*|_next).*)'],
}
authConfig.js
export const authConfig = {
pages: {
signIn: "/login",
},
callbacks: {
async authorized({ auth, request: { nextUrl } }) {
console.log('authorized');
const isLoggedIn = !!auth?.user;
const isOnLogin = nextUrl.pathname.startsWith('/login');
const callbackUrl = nextUrl.searchParams.get('callbackUrl') || '/dashboard';
if (!isLoggedIn) {
return false;
} else if (isLoggedIn && isOnLogin) {
return Response.redirect(new URL(decodeURIComponent(callbackUrl), nextUrl));
}
return true;
},
},
providers: [],
};
auth.js
import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";
import { authConfig } from "./authConfig";
import { login } from "./lib/actions";
export const {
signIn,
signOut,
auth
} = NextAuth({
...authConfig,
providers: [
Credentials({
async authorize(credentials) {
try {
const user = await login(credentials);
return user;
} catch (error) {
throw error;
}
},
}),
],
callbacks: {
async jwt({ token, user }) {
if (user) {
const roleLevel = ['user', 'worker', 'admin'];
token.username = user.username;
token.fullname = user.fullname;
token.role = user.role;
token.roleLevel = roleLevel.indexOf(user.role);
}
return token;
},
async session({ session, token }) {
if (token) {
session.user.username = token.username;
session.user.fullname = token.fullname;
session.user.role = token.role;
session.user.roleLevel = token.roleLevel;
}
return session;
},
},
});
Так вот логин, и все другие функции работают хорошо, но вот есть проблемка, если например пользователь с ролью админ, был удален, и он еще находится в систему, то он может без проблем создать новую запись, так вот я хочу сделать проверку на то существует ли пользователь, что если бы он был удален, то при любом взаимодействие с системой его выкидывало на логин. Но не могу понять как правильно это реализовать, К примеру вот функция addNewUser
export const addNewUser = async (formData) => {
try {
const { username, fullname, password, role } = Object.fromEntries(formData);
const session = await auth();
if (session.user.role !== 'admin') {
return { isSuccess: false, status: 'error', message: 'you don`t have access!' };
}
if (!username || !fullname || !password || !role) {
return { isSuccess: false, status: 'error', message: 'One of the fields is empty!' };
}
const connection = await ConnectToDB();
const usernameQuery = 'SELECT username FROM users WHERE BINARY username = ?';
const [isUserExist] = await connection.execute(usernameQuery, [username]);
if (isUserExist.length > 0) {
return { isSuccess: false, status: 'error', message: 'The username is already taken!' };
}
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(password, salt);
const addQuery = 'INSERT INTO users (username, fullname, password, role) VALUES (?, ?, ?, ?)';
const [user] = await connection.execute(addQuery, [username, fullname, hashedPassword, role]);
if (user.affectedRows === 0) {
return { isSuccess: false, status: 'error', message: 'There was an error when adding it!' };
} else {
revalidatePath('/users');
return { isSuccess: true, status: 'success', message: 'A user has been added!', data: user[0] };
}
}
catch (e) {
return { isSuccess: false, status: 'error', message: e.sqlMessage ?? (e.message ?? e) };
}
}
тут много проверок, и одна из них что пользователь является админом через const session = await auth();
Сразу отвечу на то что можно же добавить
const usernameQuery = 'SELECT username FROM users WHERE BINARY username = ?';
const [isUserExist] = await connection.execute(usernameQuery, [session.username]);
if (isUserExist.length === 0) {
// Ошибка что пользователя нету, и перенаправить на логин.
}
Да такой способ сработает, но когда запросов много, нужно в каждый добавить такую проверку, это очень много, и хотелось бы один раз написать в middleware который при каждом взаимодействие сам проверит, и выдаст ошибку если нет пользователя.
Еще в middleware authorized у меня почему-то пустой auth?.user = {} и я не могу вытащить из него имя пользователя чтобы проверить его. А если пытаюсь получить сессию или что-то подобное типа
import { getSession } from "./lib/actions";
получаю ошибку Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
Поэтому прошу совета, как правильно реализовать проверку существует ли пользователь.