09101122
This commit is contained in:
parent
5630af88ba
commit
6e95554e0c
|
@ -10,9 +10,14 @@ import { AuthModule } from './auth/auth.module';
|
|||
import { ScheduleModule } from '@nestjs/schedule';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { TasksModule } from './tasks/tasks.module';
|
||||
import { JwtModule } from '@nestjs/jwt';
|
||||
import { env } from './env';
|
||||
|
||||
@Module({
|
||||
imports: [ScheduleModule.forRoot(), TrpcModule, RedisModule, QueueModule, TransformModule, AuthModule, TasksModule],
|
||||
imports: [ScheduleModule.forRoot(), JwtModule.register({
|
||||
global: true,
|
||||
secret: env.JWT_SECRET
|
||||
}), TrpcModule, RedisModule, QueueModule, TransformModule, AuthModule, TasksModule],
|
||||
providers: [RedisService, SocketGateway, ConfigService],
|
||||
})
|
||||
export class AppModule { }
|
||||
|
|
|
@ -12,8 +12,6 @@ export class AuthController {
|
|||
@Get("user-profile")
|
||||
async getUserProfile(@Req() request: Request) {
|
||||
const user: JwtPayload = (request as any).user
|
||||
console.log(user)
|
||||
// console.log(request)
|
||||
return this.authService.getUserProfile(user)
|
||||
}
|
||||
@Post('login')
|
||||
|
|
|
@ -15,7 +15,7 @@ export class AuthGuard implements CanActivate {
|
|||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const token = this.extractTokenFromHeader(request);
|
||||
console.log(token)
|
||||
|
||||
if (!token) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ export class AuthGuard implements CanActivate {
|
|||
return true;
|
||||
}
|
||||
|
||||
private extractTokenFromHeader(request: Request): string | undefined {
|
||||
extractTokenFromHeader(request: Request): string | undefined {
|
||||
const [type, token] = request.headers.authorization?.split(' ') ?? [];
|
||||
return type === 'Bearer' ? token : undefined;
|
||||
}
|
||||
|
|
|
@ -9,11 +9,6 @@ import { DepartmentService } from '@server/models/department/department.service'
|
|||
|
||||
@Module({
|
||||
providers: [AuthService, StaffService, RoleMapService, DepartmentService],
|
||||
imports: [JwtModule.register({
|
||||
global: true,
|
||||
secret: env.JWT_SECRET,
|
||||
signOptions: { expiresIn: '60s' },
|
||||
}),],
|
||||
controllers: [AuthController],
|
||||
exports: [AuthService]
|
||||
})
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { TrpcService } from './trpc.service';
|
||||
|
||||
describe('TrpcService', () => {
|
||||
let service: TrpcService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [TrpcService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<TrpcService>(TrpcService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { initTRPC, TRPCError } from '@trpc/server';
|
||||
import superjson from 'superjson-cjs';
|
||||
import * as trpcExpress from '@trpc/server/adapters/express';
|
||||
|
@ -9,7 +9,7 @@ import { JwtService } from '@nestjs/jwt';
|
|||
type Context = Awaited<ReturnType<TrpcService['createContext']>>;
|
||||
@Injectable()
|
||||
export class TrpcService {
|
||||
constructor(private readonly jwtService: JwtService) { }
|
||||
|
||||
async createContext({
|
||||
req,
|
||||
res,
|
||||
|
@ -17,10 +17,11 @@ export class TrpcService {
|
|||
const token = req.headers.authorization?.split(' ')[1];
|
||||
let tokenData: JwtPayload | undefined = undefined;
|
||||
let staff: Staff | undefined = undefined;
|
||||
console.log(token)
|
||||
if (token) {
|
||||
try {
|
||||
// Verify JWT token and extract tokenData
|
||||
tokenData = await this.jwtService.verifyAsync(token, { secret: env.JWT_SECRET }) as JwtPayload;
|
||||
const jwtService = new JwtService()
|
||||
tokenData = await jwtService.verifyAsync(token, { secret: env.JWT_SECRET }) as JwtPayload;
|
||||
if (tokenData) {
|
||||
// Fetch staff details from the database using tokenData.id
|
||||
staff = await db.staff.findUnique({ where: { id: tokenData.sub } });
|
||||
|
@ -35,7 +36,7 @@ export class TrpcService {
|
|||
}
|
||||
|
||||
return {
|
||||
staff,
|
||||
staff
|
||||
};
|
||||
};
|
||||
trpc = initTRPC.context<Context>().create({
|
||||
|
|
|
@ -6,13 +6,16 @@ import QueryProvider from './providers/query-provider'
|
|||
import { router } from './routes';
|
||||
import { AuthProvider } from './providers/auth-provider';
|
||||
import ThemeProvider from './providers/theme-provider';
|
||||
import { App as AntdApp } from 'antd';
|
||||
function App() {
|
||||
|
||||
return (
|
||||
<AuthProvider>
|
||||
<QueryProvider>
|
||||
<ThemeProvider>
|
||||
<AntdApp>
|
||||
<RouterProvider router={router}></RouterProvider>
|
||||
</AntdApp>
|
||||
</ThemeProvider>
|
||||
</QueryProvider>
|
||||
</AuthProvider>
|
||||
|
|
|
@ -8,29 +8,28 @@ import SineWave from '../components/presentation/animation/sine-wave';
|
|||
const LoginPage: React.FC = () => {
|
||||
const [showLogin, setShowLogin] = useState(true);
|
||||
const [registerLoading, setRegisterLoading] = useState(false);
|
||||
const { login, isAuthenticated } = useAuth();
|
||||
const { login, isAuthenticated, signup } = useAuth();
|
||||
const loginFormRef = useRef<any>(null);
|
||||
const registerFormRef = useRef<any>(null);
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate()
|
||||
const navigate = useNavigate();
|
||||
|
||||
const onFinishLogin = async (values: any) => {
|
||||
try {
|
||||
const { username, password } = values;
|
||||
await login(username, password);
|
||||
message.success('登录成功!');
|
||||
} catch (err) {
|
||||
message.warning('用户名或密码错误!');
|
||||
message.error('用户名或密码错误!');
|
||||
console.error(err);
|
||||
}
|
||||
};
|
||||
|
||||
const onFinishRegister = async (values: any) => {
|
||||
setRegisterLoading(true);
|
||||
const { username, password, phoneNumber } = values;
|
||||
try {
|
||||
// await wp.RegisterUser().create({
|
||||
// ...values,
|
||||
// custom_data: { org_unit: values.org_unit },
|
||||
// });
|
||||
await signup(username, password, phoneNumber);
|
||||
message.success('注册成功!');
|
||||
setShowLogin(true);
|
||||
loginFormRef.current.submit();
|
||||
|
@ -51,13 +50,10 @@ const LoginPage: React.FC = () => {
|
|||
|
||||
return (
|
||||
<div className="flex justify-center items-center h-screen w-full bg-layout">
|
||||
<div className="flex items-center transition-all overflow-hidden bg-container rounded-xl" style={{ width: 800, height: 600, padding: 0 }}>
|
||||
<div className="flex items-center transition-all overflow-hidden bg-container rounded-xl " style={{ width: 800, height: 600 }}>
|
||||
<div className="flex-1 py-10 px-10">
|
||||
{showLogin ? (
|
||||
<>
|
||||
<Link to="/" className="text-gray-400 text-sm hover:text-primary hover:cursor-pointer">
|
||||
返回首页
|
||||
</Link>
|
||||
<div className="text-center text-2xl text-primary select-none">
|
||||
<span className="px-2">登录</span>
|
||||
</div>
|
||||
|
@ -77,33 +73,28 @@ const LoginPage: React.FC = () => {
|
|||
</Form>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div
|
||||
onClick={() => setShowLogin(true)}
|
||||
className="text-sm text-gray-400 hover:cursor-pointer hover:text-primary"
|
||||
>
|
||||
返回登录
|
||||
</div>
|
||||
<div >
|
||||
|
||||
<div className="text-center text-2xl text-primary">注册</div>
|
||||
<Form requiredMark="optional" ref={registerFormRef} onFinish={onFinishRegister} layout="vertical" size="large">
|
||||
<Form.Item name="username" label="用户名" rules={[
|
||||
{ required: true, message: '请输入用户名' },
|
||||
{ min: 3, max: 15, message: '用户名长度在 3 到 15 个字符' }
|
||||
]}>
|
||||
<Input placeholder="输入用户名" />
|
||||
<Input />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="deptId" label="单位" rules={[{ required: true, message: '请选择单位' }]}>
|
||||
<DepartmentSelect />
|
||||
<Form.Item name="phoneNumber" label="手机号" rules={[
|
||||
{ required: false },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入有效的手机号' }
|
||||
]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="password" label="密码" rules={[
|
||||
{ required: true, message: '请输入密码' },
|
||||
{ min: 6, message: '密码长度不能小于 6 位' }
|
||||
]}>
|
||||
<Input.Password placeholder="输入密码" />
|
||||
<Input.Password />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="repeatPass" label="确认密码" dependencies={['password']} hasFeedback rules={[
|
||||
{ required: true, message: '请再次输入密码' },
|
||||
({ getFieldValue }) => ({
|
||||
|
@ -115,7 +106,7 @@ const LoginPage: React.FC = () => {
|
|||
}
|
||||
})
|
||||
]}>
|
||||
<Input.Password placeholder="确认密码" />
|
||||
<Input.Password />
|
||||
</Form.Item>
|
||||
|
||||
<div className="flex items-center justify-center">
|
||||
|
@ -124,7 +115,7 @@ const LoginPage: React.FC = () => {
|
|||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={`transition-all h-full flex-1 text-white p-10 flex items-center justify-center bg-primary`}>
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import { useAuth } from "@web/src/providers/auth-provider"
|
||||
|
||||
export default function MainPage() {
|
||||
return <>hello,world</>
|
||||
const { user } = useAuth()
|
||||
return <>hello,{user?.username}</>
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ interface AuthContextProps {
|
|||
user: UserProfile | null;
|
||||
login: (username: string, password: string) => Promise<void>;
|
||||
logout: () => Promise<void>;
|
||||
signup: (username: string, password: string, phoneNumber?: string) => Promise<void>;
|
||||
refreshAccessToken: () => Promise<void>;
|
||||
initializeAuth: () => void;
|
||||
startTokenRefreshInterval: () => void;
|
||||
|
@ -102,6 +103,28 @@ export function AuthProvider({ children }: AuthProviderProps) {
|
|||
}
|
||||
};
|
||||
|
||||
const signup = async (username: string, password: string, phoneNumber?: string): Promise<void> => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await apiClient.post(`/auth/signup`, { username, password, phoneNumber });
|
||||
// const { access_token, refresh_token, access_token_expires_at, refresh_token_expires_at } = response.data;
|
||||
// localStorage.setItem('access_token', access_token);
|
||||
// localStorage.setItem('refresh_token', refresh_token);
|
||||
// localStorage.setItem('access_token_expires_at', access_token_expires_at);
|
||||
// localStorage.setItem('refresh_token_expires_at', refresh_token_expires_at);
|
||||
// setAccessToken(access_token);
|
||||
// setRefreshToken(refresh_token);
|
||||
// setIsAuthenticated(true);
|
||||
// startTokenRefreshInterval();
|
||||
// fetchUserProfile();
|
||||
} catch (err) {
|
||||
console.error("Signup failed", err);
|
||||
throw new Error("Signup failed");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const logout = async (): Promise<void> => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
@ -154,6 +177,7 @@ export function AuthProvider({ children }: AuthProviderProps) {
|
|||
user,
|
||||
login,
|
||||
logout,
|
||||
signup,
|
||||
refreshAccessToken,
|
||||
initializeAuth,
|
||||
startTokenRefreshInterval,
|
||||
|
|
Loading…
Reference in New Issue