import type { Context, Next } from 'hono'; import { authConfig } from '@/config/auth'; import db from '@/lib/db/client'; import { Passport } from 'passport'; import { Strategy as JwtStrategy } from 'passport-jwt'; import { Strategy as LocalStrategy } from 'passport-local'; import { v7 } from 'uuid'; import type { AuthJwtPayload } from './type'; import { ValidateUser } from './service'; // pnpm install nodemailer --save @types/nodemailer // 生成验证令牌的异步函数,接受邮箱作为参数并返回生成的验证令牌 export const generateVerificationToken = async (email: string) => { const token = v7(); const expires = new Date(Date.now() + 1000 * 60 * 60 * 24); // 24 hours const existingEmail = await getVerificationTokenByEmail(email); if (existingEmail) { await db.verificationToken.delete({ where: { id: existingEmail.id } }); } const verificationToken = await db.verificationToken.create({ data: { email, token, expires, }, }); return verificationToken; }; // 根据邮箱获取验证令牌的异步函数 export const getVerificationTokenByEmail = async (email: string) => { try { const token = await db.verificationToken.findFirst({ where: { email } }); return token; } catch (e) { console.log(e); return null; } }; export const passport = new Passport(); export const passportInitialize = () => async (c: Context, next: Next) => { const handle = passport.initialize(); await new Promise((reslove) => { handle(c.req.raw as any, (c.res as any).raw, reslove); }); await next(); }; passport.use( 'local', new LocalStrategy({ usernameField: 'credential' }, async (credential, password, done) => { console.log(credential, password); try { const user = await ValidateUser(credential, password); if (!user.success) { done({ message: user.message, code: 401 }); } else { done(null, user.user as any); } } catch (error) { done(error); } }), ); passport.use( 'jwt', new JwtStrategy( { jwtFromRequest: (req: any) => { const authHeader = req.headers.get('authorization'); return authHeader ? authHeader.startsWith('Bearer ') ? authHeader.substring(7) : null : null; }, secretOrKey: authConfig.jwtSecret, }, async (jwtPayload: AuthJwtPayload, done) => { try { return done(null, jwtPayload); } catch (error) { return done(error, false); } }, ), ); export const verifyJWT = async (c: Context) => new Promise((resolve) => { passport.authenticate('jwt', { session: false }, (err: any, user: AuthJwtPayload) => { if (err || !user) { resolve(false); return undefined; } c.set('user', user); resolve(true); })(c.req.raw, (c.res as any).raw); });