auth: fetch new user data on session
This commit is contained in:
parent
c8a3bf7038
commit
4c7ca7db06
61
src/auth.ts
61
src/auth.ts
@ -1,18 +1,30 @@
|
||||
import NextAuth from 'next-auth';
|
||||
import CredentialsProvider from 'next-auth/providers/credentials';
|
||||
import { db } from '@/db';
|
||||
import { db, GeneratedDB } from '@/db';
|
||||
import bcrypt from 'bcrypt';
|
||||
import { DBUserPayload } from '@/types/user';
|
||||
import React from 'react';
|
||||
import { SelectQueryBuilder } from 'kysely';
|
||||
import { AimeUser } from '@/types/db';
|
||||
|
||||
let basePath = process.env.BASE_PATH ?? '';
|
||||
if (basePath.endsWith('/')) basePath = basePath.slice(0, -1);
|
||||
|
||||
export const {
|
||||
handlers: { GET, POST },
|
||||
auth,
|
||||
signIn,
|
||||
signOut
|
||||
} = NextAuth({
|
||||
const selectUserProps = (builder: SelectQueryBuilder<GeneratedDB & { u: AimeUser }, 'u', {}>) => builder.leftJoin(
|
||||
eb => eb.selectFrom('chuni_profile_data as chuni')
|
||||
.where(({ eb, selectFrom }) => eb('chuni.version', '=', selectFrom('chuni_static_music')
|
||||
.select(({ fn }) => fn.max('version').as('latest'))))
|
||||
.selectAll()
|
||||
.as('chuni'),
|
||||
join => join.onRef('chuni.user', '=', 'u.id'))
|
||||
.select(({ fn }) => [
|
||||
'u.username', 'u.password', 'u.id', 'u.email', 'u.permissions', 'u.created_date', 'u.last_login_date',
|
||||
'u.suspend_expire_time',
|
||||
fn<boolean>('not isnull', ['chuni.id']).as('chuni')
|
||||
])
|
||||
.executeTakeFirst();
|
||||
|
||||
const nextAuth = NextAuth({
|
||||
pages: {
|
||||
signIn: `${basePath}/auth/login`
|
||||
},
|
||||
@ -22,8 +34,16 @@ export const {
|
||||
},
|
||||
trustHost: true,
|
||||
callbacks: {
|
||||
jwt({ token, user }) {
|
||||
async jwt({ token, user }) {
|
||||
token.user ??= user;
|
||||
const dbUser = await selectUserProps(db.selectFrom('aime_user as u')
|
||||
.where('u.id', '=', (token.user as any).id));
|
||||
|
||||
if (dbUser) {
|
||||
const { password, ...payload } = dbUser;
|
||||
token.user = { ...(token.user as any), ...payload };
|
||||
}
|
||||
|
||||
return token;
|
||||
},
|
||||
session({ session, token, user }) {
|
||||
@ -41,22 +61,9 @@ export const {
|
||||
if (typeof username !== 'string' || typeof password !== 'string')
|
||||
return null;
|
||||
|
||||
const user = await db.selectFrom('aime_user as u')
|
||||
const user = await selectUserProps(db.selectFrom('aime_user as u')
|
||||
.where(({ eb, fn }) =>
|
||||
eb(fn<string>('lower', ['u.username']), '=', username.toLowerCase().trim()))
|
||||
.leftJoin(
|
||||
eb => eb.selectFrom('chuni_profile_data as chuni')
|
||||
.where(({ eb, selectFrom }) => eb('chuni.version', '=', selectFrom('chuni_static_music')
|
||||
.select(({ fn }) => fn.max('version').as('latest'))))
|
||||
.selectAll()
|
||||
.as('chuni'),
|
||||
join => join.onRef('chuni.user', '=', 'u.id'))
|
||||
.select(({ fn }) => [
|
||||
'u.username', 'u.password', 'u.id', 'u.email', 'u.permissions', 'u.created_date', 'u.last_login_date',
|
||||
'u.suspend_expire_time',
|
||||
fn<boolean>('not isnull', ['chuni.id']).as('chuni')
|
||||
])
|
||||
.executeTakeFirst();
|
||||
eb(fn<string>('lower', ['u.username']), '=', username.toLowerCase().trim())));
|
||||
|
||||
if (!user?.password || !await bcrypt.compare(password.trim(), user.password))
|
||||
return null;
|
||||
@ -67,3 +74,11 @@ export const {
|
||||
}
|
||||
})]
|
||||
});
|
||||
|
||||
export const auth = React.cache(nextAuth.auth);
|
||||
|
||||
export const {
|
||||
handlers: { GET, POST },
|
||||
signIn,
|
||||
signOut
|
||||
} = nextAuth;
|
||||
|
Loading…
Reference in New Issue
Block a user