mirror of
https://github.com/StepanovPlaton/torrent_frontend.git
synced 2026-04-04 04:40:50 +04:00
Add login
This commit is contained in:
16
src/entities/user/index.ts
Normal file
16
src/entities/user/index.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import {
|
||||
loginFormSchema,
|
||||
loginFormFieldNames,
|
||||
LoginForm,
|
||||
} from "./schemas/auth";
|
||||
import { userSchema, User } from "./schemas/user";
|
||||
import { UserService } from "./user";
|
||||
|
||||
export {
|
||||
loginFormSchema,
|
||||
loginFormFieldNames,
|
||||
UserService,
|
||||
userSchema,
|
||||
type User,
|
||||
type LoginForm,
|
||||
};
|
||||
30
src/entities/user/schemas/auth.ts
Normal file
30
src/entities/user/schemas/auth.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { z } from "zod";
|
||||
import { userSchema } from "./user";
|
||||
|
||||
export const loginFormSchema = z.object({
|
||||
username: z.string().min(3, "Логин слишком короткий"),
|
||||
password: z.string().min(3, "Пароль слишком короткий"),
|
||||
});
|
||||
export const loginFormFieldNames = {
|
||||
username: "Логин",
|
||||
password: "Пароль",
|
||||
};
|
||||
export type LoginForm = z.infer<typeof loginFormSchema>;
|
||||
|
||||
export const tokenResponseSchema = z
|
||||
.object({
|
||||
access_token: z.string(),
|
||||
token_type: z.string(),
|
||||
})
|
||||
.transform((tokenResponse) => tokenResponse.access_token);
|
||||
export type TokenResponse = z.infer<typeof tokenResponseSchema>;
|
||||
|
||||
export const tokenDataSchema = userSchema.merge(
|
||||
z.object({
|
||||
expire: z
|
||||
.string()
|
||||
.min(1)
|
||||
.transform((d) => new Date(d)),
|
||||
})
|
||||
);
|
||||
export type TokenData = z.infer<typeof tokenDataSchema>;
|
||||
8
src/entities/user/schemas/user.ts
Normal file
8
src/entities/user/schemas/user.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const userSchema = z.object({
|
||||
id: z.number().positive(),
|
||||
name: z.string().min(3),
|
||||
email: z.string().min(3),
|
||||
});
|
||||
export type User = z.infer<typeof userSchema>;
|
||||
48
src/entities/user/user.ts
Normal file
48
src/entities/user/user.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { HTTPService } from "@/shared/utils/http";
|
||||
import {
|
||||
LoginForm,
|
||||
TokenData,
|
||||
tokenDataSchema,
|
||||
TokenResponse,
|
||||
tokenResponseSchema,
|
||||
} from "./schemas/auth";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
export abstract class UserService {
|
||||
public static async Login(loginForm: LoginForm) {
|
||||
const accessToken = await HTTPService.post<TokenResponse>(
|
||||
"/auth",
|
||||
new URLSearchParams(Object.entries(loginForm)),
|
||||
tokenResponseSchema,
|
||||
{
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
}
|
||||
);
|
||||
if (accessToken) {
|
||||
const tokenData = this.DecodeToken(accessToken);
|
||||
if (tokenData) {
|
||||
Cookies.set("access-token", accessToken, {
|
||||
secure: true,
|
||||
expires: tokenData.expire,
|
||||
});
|
||||
return tokenData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IdentifyYourself(): TokenData | undefined {
|
||||
const token = Cookies.get("access-token");
|
||||
if (token) {
|
||||
return this.DecodeToken(token);
|
||||
}
|
||||
}
|
||||
|
||||
public static DecodeToken(token: string): TokenData | undefined {
|
||||
const tokenPayload = jwtDecode(token);
|
||||
const parseResult = tokenDataSchema.safeParse(tokenPayload);
|
||||
if (parseResult.success) {
|
||||
return parseResult.data;
|
||||
} else console.error("JWT payload broken - " + parseResult.error);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user