From f67e0adea48448e8ada012bbb62f0a62f58e1afb Mon Sep 17 00:00:00 2001 From: Steven Date: Thu, 22 Jun 2023 19:11:59 +0800 Subject: [PATCH] chore: use auth api v1 in frontend --- api/v1/auth.go | 23 ++++++------ web/src/helpers/api.ts | 47 ++++++++++-------------- web/src/pages/Auth.tsx | 54 ++++------------------------ web/src/pages/ShortcutRedirector.tsx | 2 +- web/src/services/shortcutService.ts | 8 ++--- web/src/services/userService.ts | 8 ++--- web/src/types/modules/user.d.ts | 6 ---- 7 files changed, 45 insertions(+), 103 deletions(-) diff --git a/api/v1/auth.go b/api/v1/auth.go index f6f81a5..0d444a4 100644 --- a/api/v1/auth.go +++ b/api/v1/auth.go @@ -20,12 +20,12 @@ func getUserIDContextKey() string { return userIDContextKey } -type SignUpRequest struct { +type SignInRequest struct { Username string `json:"username"` Password string `json:"password"` } -type SignInRequest struct { +type SignUpRequest struct { Username string `json:"username"` Password string `json:"password"` } @@ -52,8 +52,7 @@ func (s *APIV1Service) registerAuthRoutes(g *echo.Group, secret string) { // Compare the stored hashed password, with the hashed version of the password that was received. if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(signin.Password)); err != nil { - // If the two passwords don't match, return a 401 status. - return echo.NewHTTPError(http.StatusUnauthorized, "Incorrect password").SetInternal(err) + return echo.NewHTTPError(http.StatusUnauthorized, "Unmatched username and password").SetInternal(err) } if err := auth.GenerateTokensAndSetCookies(c, user, secret); err != nil { @@ -69,28 +68,28 @@ func (s *APIV1Service) registerAuthRoutes(g *echo.Group, secret string) { return echo.NewHTTPError(http.StatusBadRequest, "Malformatted signup request").SetInternal(err) } - user := &store.User{ - Username: signup.Username, - Nickname: signup.Username, - } passwordHash, err := bcrypt.GenerateFromPassword([]byte(signup.Password), bcrypt.DefaultCost) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to generate password hash").SetInternal(err) } - user.PasswordHash = string(passwordHash) + create := &store.User{ + Username: signup.Username, + Nickname: signup.Username, + PasswordHash: string(passwordHash), + } existingUsers, err := s.Store.ListUsers(ctx, &store.FindUser{}) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find existing users").SetInternal(err) } // The first user to sign up is an admin by default. if len(existingUsers) == 0 { - user.Role = store.RoleAdmin + create.Role = store.RoleAdmin } else { - user.Role = store.RoleUser + create.Role = store.RoleUser } - user, err = s.Store.CreateUser(ctx, user) + user, err := s.Store.CreateUser(ctx, create) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create user").SetInternal(err) } diff --git a/web/src/helpers/api.ts b/web/src/helpers/api.ts index a21f560..5aaaa8c 100644 --- a/web/src/helpers/api.ts +++ b/web/src/helpers/api.ts @@ -1,56 +1,45 @@ import axios from "axios"; -type ResponseObject = { - data: T; - error?: string; - message?: string; -}; - export function getSystemStatus() { - return axios.get>("/api/status"); + return axios.get("/api/v1/status"); } -export function signin(email: string, password: string) { - return axios.post>("/api/auth/signin", { - email, +export function signin(username: string, password: string) { + return axios.post("/api/v1/auth/signin", { + username, password, }); } -export function signup(email: string, password: string) { - return axios.post>("/api/auth/signup", { - email, +export function signup(username: string, password: string) { + return axios.post("/api/v1/auth/signup", { + username, password, - name: email, }); } export function signout() { - return axios.post("/api/auth/logout"); -} - -export function createUser(userCreate: UserCreate) { - return axios.post>("/api/user", userCreate); + return axios.post("/api/v1/auth/logout"); } export function getMyselfUser() { - return axios.get>("/api/user/me"); + return axios.get("/api/v1/user/me"); } export function getUserList() { - return axios.get>("/api/user"); + return axios.get("/api/v1/user"); } export function getUserById(id: number) { - return axios.get>(`/api/user/${id}`); + return axios.get(`/api/v1/user/${id}`); } export function patchUser(userPatch: UserPatch) { - return axios.patch>(`/api/user/${userPatch.id}`, userPatch); + return axios.patch(`/api/v1/user/${userPatch.id}`, userPatch); } export function deleteUser(userDelete: UserDelete) { - return axios.delete(`/api/user/${userDelete.id}`); + return axios.delete(`/api/v1/user/${userDelete.id}`); } export function getShortcutList(shortcutFind?: ShortcutFind) { @@ -58,21 +47,21 @@ export function getShortcutList(shortcutFind?: ShortcutFind) { if (shortcutFind?.creatorId) { queryList.push(`creatorId=${shortcutFind.creatorId}`); } - return axios.get>(`/api/shortcut?${queryList.join("&")}`); + return axios.get(`/api/v1/shortcut?${queryList.join("&")}`); } export function getShortcutWithNameAndWorkspaceName(workspaceName: string, shortcutName: string) { - return axios.get>(`/api/workspace/${workspaceName}/shortcut/${shortcutName}`); + return axios.get(`/api/v1/workspace/${workspaceName}/shortcut/${shortcutName}`); } export function createShortcut(shortcutCreate: ShortcutCreate) { - return axios.post>("/api/shortcut", shortcutCreate); + return axios.post("/api/v1/shortcut", shortcutCreate); } export function patchShortcut(shortcutPatch: ShortcutPatch) { - return axios.patch>(`/api/shortcut/${shortcutPatch.id}`, shortcutPatch); + return axios.patch(`/api/v1/shortcut/${shortcutPatch.id}`, shortcutPatch); } export function deleteShortcutById(shortcutId: ShortcutId) { - return axios.delete(`/api/shortcut/${shortcutId}`); + return axios.delete(`/api/v1/shortcut/${shortcutId}`); } diff --git a/web/src/pages/Auth.tsx b/web/src/pages/Auth.tsx index c61d8ba..1e99bf5 100644 --- a/web/src/pages/Auth.tsx +++ b/web/src/pages/Auth.tsx @@ -3,21 +3,13 @@ import React, { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { toast } from "react-hot-toast"; import * as api from "../helpers/api"; -import { validate, ValidatorConfig } from "../helpers/validator"; import { userService } from "../services"; import useLoading from "../hooks/useLoading"; import Icon from "../components/Icon"; -const validateConfig: ValidatorConfig = { - minLength: 3, - maxLength: 24, - noSpace: true, - noChinese: true, -}; - const Auth: React.FC = () => { const navigate = useNavigate(); - const [email, setEmail] = useState(""); + const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const actionBtnLoadingState = useLoading(false); @@ -26,19 +18,11 @@ const Auth: React.FC = () => { navigate("/"); return; } - - api.getSystemStatus().then(({ data }) => { - const { data: status } = data; - if (status.profile.mode === "dev") { - setEmail("frank@shortify.demo"); - setPassword("secret"); - } - }); }, []); - const handleEmailInputChanged = (e: React.ChangeEvent) => { + const handleUsernameInputChanged = (e: React.ChangeEvent) => { const text = e.target.value as string; - setEmail(text); + setUsername(text); }; const handlePasswordInputChanged = (e: React.ChangeEvent) => { @@ -51,21 +35,9 @@ const Auth: React.FC = () => { return; } - const emailValidResult = validate(email, validateConfig); - if (!emailValidResult.result) { - toast.error("Email: " + emailValidResult.reason); - return; - } - - const passwordValidResult = validate(password, validateConfig); - if (!passwordValidResult.result) { - toast.error("Password: " + passwordValidResult.reason); - return; - } - try { actionBtnLoadingState.setLoading(); - await api.signin(email, password); + await api.signin(username, password); const user = await userService.doSignIn(); if (user) { navigate("/", { @@ -86,21 +58,9 @@ const Auth: React.FC = () => { return; } - const emailValidResult = validate(email, validateConfig); - if (!emailValidResult.result) { - toast.error("Email: " + emailValidResult.reason); - return; - } - - const passwordValidResult = validate(password, validateConfig); - if (!passwordValidResult.result) { - toast.error("Password: " + passwordValidResult.reason); - return; - } - try { actionBtnLoadingState.setLoading(); - await api.signup(email, password); + await api.signup(username, password); const user = await userService.doSignIn(); if (user) { navigate("/", { @@ -129,8 +89,8 @@ const Auth: React.FC = () => {
- Email - + Username +
Password diff --git a/web/src/pages/ShortcutRedirector.tsx b/web/src/pages/ShortcutRedirector.tsx index b7f09ef..248d0b4 100644 --- a/web/src/pages/ShortcutRedirector.tsx +++ b/web/src/pages/ShortcutRedirector.tsx @@ -16,7 +16,7 @@ const ShortcutRedirector: React.FC = () => { const workspaceName = params.workspaceName || ""; const shortcutName = params.shortcutName || ""; getShortcutWithNameAndWorkspaceName(workspaceName, shortcutName) - .then(({ data: { data: shortcut } }) => { + .then(({ data: shortcut }) => { if (shortcut) { window.location.href = shortcut.link; } else { diff --git a/web/src/services/shortcutService.ts b/web/src/services/shortcutService.ts index f3ed8c6..3402ce7 100644 --- a/web/src/services/shortcutService.ts +++ b/web/src/services/shortcutService.ts @@ -16,14 +16,14 @@ const shortcutService = { }, fetchWorkspaceShortcuts: async () => { - const { data } = (await api.getShortcutList({})).data; + const data = (await api.getShortcutList({})).data; const shortcuts = data.map((s) => convertResponseModelShortcut(s)); store.dispatch(setShortcuts(shortcuts)); return shortcuts; }, getMyAllShortcuts: async () => { - const { data } = (await api.getShortcutList()).data; + const data = (await api.getShortcutList()).data; const shortcuts = data.map((s) => convertResponseModelShortcut(s)); store.dispatch(setShortcuts(shortcuts)); }, @@ -39,13 +39,13 @@ const shortcutService = { }, createShortcut: async (shortcutCreate: ShortcutCreate) => { - const { data } = (await api.createShortcut(shortcutCreate)).data; + const data = (await api.createShortcut(shortcutCreate)).data; const shortcut = convertResponseModelShortcut(data); store.dispatch(createShortcut(shortcut)); }, patchShortcut: async (shortcutPatch: ShortcutPatch) => { - const { data } = (await api.patchShortcut(shortcutPatch)).data; + const data = (await api.patchShortcut(shortcutPatch)).data; const shortcut = convertResponseModelShortcut(data); store.dispatch(patchShortcut(shortcut)); }, diff --git a/web/src/services/userService.ts b/web/src/services/userService.ts index c116f1c..9b8025d 100644 --- a/web/src/services/userService.ts +++ b/web/src/services/userService.ts @@ -17,7 +17,7 @@ const userService = { initialState: async () => { try { - const { data: user } = (await api.getMyselfUser()).data; + const user = (await api.getMyselfUser()).data; if (user) { store.dispatch(setUser(convertResponseModelUser(user))); } @@ -27,7 +27,7 @@ const userService = { }, doSignIn: async () => { - const { data: user } = (await api.getMyselfUser()).data; + const user = (await api.getMyselfUser()).data; if (user) { store.dispatch(setUser(convertResponseModelUser(user))); } else { @@ -42,7 +42,7 @@ const userService = { }, getUserById: async (userId: UserId) => { - const { data: user } = (await api.getUserById(userId)).data; + const user = (await api.getUserById(userId)).data; if (user) { return convertResponseModelUser(user); } else { @@ -51,7 +51,7 @@ const userService = { }, patchUser: async (userPatch: UserPatch): Promise => { - const { data } = (await api.patchUser(userPatch)).data; + const data = (await api.patchUser(userPatch)).data; if (userPatch.id === store.getState().user.user?.id) { const user = convertResponseModelUser(data); store.dispatch(patchUser(user)); diff --git a/web/src/types/modules/user.d.ts b/web/src/types/modules/user.d.ts index 9c2307c..9867e23 100644 --- a/web/src/types/modules/user.d.ts +++ b/web/src/types/modules/user.d.ts @@ -15,12 +15,6 @@ interface User { role: Role; } -interface UserCreate { - email: string; - password: string; - displayName: string; -} - interface UserPatch { id: UserId;