diff --git a/api/v1/auth.go b/api/v1/auth.go index 52102605..a2116e53 100644 --- a/api/v1/auth.go +++ b/api/v1/auth.go @@ -28,6 +28,7 @@ var ( type SignIn struct { Username string `json:"username"` Password string `json:"password"` + Remember bool `json:"remember"` } type SSOSignIn struct { @@ -104,7 +105,12 @@ func (s *APIV1Service) SignIn(c echo.Context) error { return echo.NewHTTPError(http.StatusUnauthorized, "Incorrect login credentials, please try again") } - accessToken, err := auth.GenerateAccessToken(user.Username, user.ID, time.Now().Add(auth.AccessTokenDuration), []byte(s.Secret)) + var expireAt time.Time + if !signin.Remember { + expireAt = time.Now().Add(auth.AccessTokenDuration) + } + + accessToken, err := auth.GenerateAccessToken(user.Username, user.ID, expireAt, []byte(s.Secret)) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to generate tokens, err: %s", err)).SetInternal(err) } diff --git a/web/src/helpers/api.ts b/web/src/helpers/api.ts index 5356dec9..6d31ac0f 100644 --- a/web/src/helpers/api.ts +++ b/web/src/helpers/api.ts @@ -17,10 +17,11 @@ export function vacuumDatabase() { return axios.post("/api/v1/system/vacuum"); } -export function signin(username: string, password: string) { +export function signin(username: string, password: string, remember: boolean) { return axios.post("/api/v1/auth/signin", { username, password, + remember, }); } diff --git a/web/src/locales/en.json b/web/src/locales/en.json index 4421fe57..6928d912 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -33,6 +33,7 @@ "explore": "Explore", "sign-in": "Sign in", "sign-in-with": "Sign in with {{provider}}", + "remember-me": "Remember me", "or": "or", "sign-up": "Sign up", "sign-out": "Sign out", diff --git a/web/src/locales/zh-Hans.json b/web/src/locales/zh-Hans.json index 63401921..6a27f705 100644 --- a/web/src/locales/zh-Hans.json +++ b/web/src/locales/zh-Hans.json @@ -56,6 +56,7 @@ "pin": "置顶", "preview": "预览", "profile": "个人资料", + "remember-me": "保持登录", "rename": "改名", "reset": "重置", "resources": "资源库", diff --git a/web/src/pages/SignIn.tsx b/web/src/pages/SignIn.tsx index 91eec6a7..8475dfd5 100644 --- a/web/src/pages/SignIn.tsx +++ b/web/src/pages/SignIn.tsx @@ -1,4 +1,4 @@ -import { Button, Divider, Input } from "@mui/joy"; +import { Button, Checkbox, Divider, Input } from "@mui/joy"; import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import { Link } from "react-router-dom"; @@ -19,6 +19,7 @@ const SignIn = () => { const mode = systemStatus.profile.mode; const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); + const [remember, setRemember] = useState(true); const disablePasswordLogin = systemStatus.disablePasswordLogin; const [identityProviderList, setIdentityProviderList] = useState([]); @@ -71,7 +72,7 @@ const SignIn = () => { try { actionBtnLoadingState.setLoading(); - await api.signin(username, password); + await api.signin(username, password, remember); const user = await userStore.doSignIn(); if (user) { window.location.href = "/"; @@ -138,6 +139,9 @@ const SignIn = () => { /> +
+ setRemember(e.target.checked)} /> +