monorepo/server/auth/utils.ts

102 lines
3.2 KiB
TypeScript

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);
});