diff --git a/api/system.go b/api/system.go index 53d93502..687d5c2f 100644 --- a/api/system.go +++ b/api/system.go @@ -3,6 +3,6 @@ package api import "github.com/usememos/memos/server/profile" type SystemStatus struct { - Owner *User `json:"owner"` + Host *User `json:"host"` Profile *profile.Profile `json:"profile"` } diff --git a/api/user.go b/api/user.go index ecf521b8..cf1757eb 100644 --- a/api/user.go +++ b/api/user.go @@ -4,16 +4,16 @@ package api type Role string const ( - // Owner is the OWNER role. - Owner Role = "OWNER" + // Host is the HOST role. + Host Role = "HOST" // NormalUser is the USER role. NormalUser Role = "USER" ) func (e Role) String() string { switch e { - case Owner: - return "OWNER" + case Host: + return "HOST" case NormalUser: return "USER" } diff --git a/server/auth.go b/server/auth.go index 1e26b017..c9ed3e52 100644 --- a/server/auth.go +++ b/server/auth.go @@ -60,17 +60,17 @@ func (s *Server) registerAuthRoutes(g *echo.Group) { }) g.POST("/auth/signup", func(c echo.Context) error { - // Don't allow to signup by this api if site owner existed. - ownerUserType := api.Owner - ownerUserFind := api.UserFind{ - Role: &ownerUserType, + // Don't allow to signup by this api if site host existed. + hostUserType := api.Host + hostUserFind := api.UserFind{ + Role: &hostUserType, } - ownerUser, err := s.Store.FindUser(&ownerUserFind) + hostUser, err := s.Store.FindUser(&hostUserFind) if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find owner user").SetInternal(err) + return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find host user").SetInternal(err) } - if ownerUser != nil { - return echo.NewHTTPError(http.StatusUnauthorized, "Site Owner existed, please contact the site owner to signin account firstly.").SetInternal(err) + if hostUser != nil { + return echo.NewHTTPError(http.StatusUnauthorized, "Site Host existed, please contact the site host to signin account firstly.").SetInternal(err) } signup := &api.Signup{} diff --git a/server/system.go b/server/system.go index 04a82c8f..d21b0b66 100644 --- a/server/system.go +++ b/server/system.go @@ -21,22 +21,22 @@ func (s *Server) registerSystemRoutes(g *echo.Group) { }) g.GET("/status", func(c echo.Context) error { - ownerUserType := api.Owner - ownerUserFind := api.UserFind{ - Role: &ownerUserType, + hostUserType := api.Host + hostUserFind := api.UserFind{ + Role: &hostUserType, } - ownerUser, err := s.Store.FindUser(&ownerUserFind) + hostUser, err := s.Store.FindUser(&hostUserFind) if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find owner user").SetInternal(err) + return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find host user").SetInternal(err) } - if ownerUser != nil { + if hostUser != nil { // data desensitize - ownerUser.OpenID = "" + hostUser.OpenID = "" } systemStatus := api.SystemStatus{ - Owner: ownerUser, + Host: hostUser, Profile: s.Profile, } diff --git a/server/user.go b/server/user.go index cf51b94d..629158de 100644 --- a/server/user.go +++ b/server/user.go @@ -143,7 +143,7 @@ func (s *Server) registerUserRoutes(g *echo.Group) { } if currentUser == nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Current session user not found with ID: %d", currentUserID)).SetInternal(err) - } else if currentUser.Role != api.Owner { + } else if currentUser.Role != api.Host { return echo.NewHTTPError(http.StatusForbidden, "Access forbidden for current session user").SetInternal(err) } diff --git a/store/db/migration/0.2/00__user_role.sql b/store/db/migration/0.2/00__user_role.sql new file mode 100644 index 00000000..c883c199 --- /dev/null +++ b/store/db/migration/0.2/00__user_role.sql @@ -0,0 +1,56 @@ +-- change user role field from "OWNER"/"USER" to "HOST"/"USER". + +PRAGMA foreign_keys = off; +BEGIN TRANSACTION; + +DROP TABLE IF EXISTS _user_old; + +ALTER TABLE + user RENAME TO _user_old; + +CREATE TABLE user ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + row_status TEXT NOT NULL CHECK (row_status IN ('NORMAL', 'ARCHIVED')) DEFAULT 'NORMAL', + email TEXT NOT NULL UNIQUE, + role TEXT NOT NULL CHECK (role IN ('HOST', 'USER')) DEFAULT 'USER', + name TEXT NOT NULL, + password_hash TEXT NOT NULL, + open_id TEXT NOT NULL UNIQUE +); + +INSERT INTO user ( + id, created_ts, updated_ts, row_status, + email, name, password_hash, open_id +) +SELECT + id, + created_ts, + updated_ts, + row_status, + email, + name, + password_hash, + open_id +FROM + _user_old; + +UPDATE + user +SET + role = 'HOST' +WHERE + id IN ( + SELECT + id + FROM + _user_old + WHERE + role = 'OWNER' + ); + +DROP TABLE IF EXISTS _user_old; + +COMMIT; +PRAGMA foreign_keys = on; diff --git a/store/db/migration/LATEST__SCHEMA.sql b/store/db/migration/LATEST__SCHEMA.sql index 79da404e..e27d4ca9 100644 --- a/store/db/migration/LATEST__SCHEMA.sql +++ b/store/db/migration/LATEST__SCHEMA.sql @@ -13,7 +13,7 @@ CREATE TABLE user ( -- allowed row status are 'NORMAL', 'ARCHIVED'. row_status TEXT NOT NULL CHECK (row_status IN ('NORMAL', 'ARCHIVED')) DEFAULT 'NORMAL', email TEXT NOT NULL UNIQUE, - role TEXT NOT NULL CHECK (role IN ('OWNER', 'USER')) DEFAULT 'USER', + role TEXT NOT NULL CHECK (role IN ('HOST', 'USER')) DEFAULT 'USER', name TEXT NOT NULL, password_hash TEXT NOT NULL, open_id TEXT NOT NULL UNIQUE diff --git a/store/db/seed/10001__user.sql b/store/db/seed/10001__user.sql index 9c3e9f16..cda2e750 100644 --- a/store/db/seed/10001__user.sql +++ b/store/db/seed/10001__user.sql @@ -11,8 +11,8 @@ VALUES ( 101, 'demo@usememos.com', - 'OWNER', - 'Demo Owner', + 'HOST', + 'Demo Host', 'demo_open_id', -- raw password: secret '$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK' diff --git a/store/user.go b/store/user.go index 19cd3689..f52b34c7 100644 --- a/store/user.go +++ b/store/user.go @@ -106,7 +106,7 @@ func createUser(db *sql.DB, create *api.UserCreate) (*userRaw, error) { open_id ) VALUES (?, ?, ?, ?, ?) - RETURNING id, email, role, name, password_hash, open_id, created_ts, updated_ts + RETURNING id, email, role, name, password_hash, open_id, created_ts, updated_ts, row_status `, create.Email, create.Role, @@ -130,6 +130,7 @@ func createUser(db *sql.DB, create *api.UserCreate) (*userRaw, error) { &userRaw.OpenID, &userRaw.CreatedTs, &userRaw.UpdatedTs, + &userRaw.RowStatus, ); err != nil { return nil, FormatError(err) } @@ -162,7 +163,7 @@ func patchUser(db *sql.DB, patch *api.UserPatch) (*userRaw, error) { UPDATE user SET `+strings.Join(set, ", ")+` WHERE id = ? - RETURNING id, email, role, name, password_hash, open_id, created_ts, updated_ts + RETURNING id, email, role, name, password_hash, open_id, created_ts, updated_ts, row_status `, args...) if err != nil { return nil, FormatError(err) @@ -180,6 +181,7 @@ func patchUser(db *sql.DB, patch *api.UserPatch) (*userRaw, error) { &userRaw.OpenID, &userRaw.CreatedTs, &userRaw.UpdatedTs, + &userRaw.RowStatus, ); err != nil { return nil, FormatError(err) } @@ -218,7 +220,8 @@ func findUserList(db *sql.DB, find *api.UserFind) ([]*userRaw, error) { password_hash, open_id, created_ts, - updated_ts + updated_ts, + row_status FROM user WHERE `+strings.Join(where, " AND ")+` ORDER BY created_ts DESC`, @@ -241,6 +244,7 @@ func findUserList(db *sql.DB, find *api.UserFind) ([]*userRaw, error) { &userRaw.OpenID, &userRaw.CreatedTs, &userRaw.UpdatedTs, + &userRaw.RowStatus, ); err != nil { fmt.Println(err) return nil, FormatError(err) diff --git a/web/src/components/SettingDialog.tsx b/web/src/components/SettingDialog.tsx index 6499499a..8a014032 100644 --- a/web/src/components/SettingDialog.tsx +++ b/web/src/components/SettingDialog.tsx @@ -48,7 +48,7 @@ const SettingDialog: React.FC = (props: Props) => { 🏟 Preferences - {user?.role === "OWNER" ? ( + {user?.role === "HOST" ? ( <> Admin
diff --git a/web/src/components/UserBanner.tsx b/web/src/components/UserBanner.tsx index 0d429b69..a03ece45 100644 --- a/web/src/components/UserBanner.tsx +++ b/web/src/components/UserBanner.tsx @@ -28,7 +28,7 @@ const UserBanner: React.FC = () => { if (locationService.getState().pathname === "/") { api.getSystemStatus().then(({ data }) => { const { data: status } = data; - setUsername(status.owner.name); + setUsername(status.host.name); }); } else { const currentUserId = userService.getCurrentUserId(); @@ -51,7 +51,7 @@ const UserBanner: React.FC = () => {
{username} - {user?.role === "OWNER" ? MOD : null} + {user?.role === "HOST" ? MOD : null}
diff --git a/web/src/less/signin.less b/web/src/less/signin.less index 0ae84011..f5762d1d 100644 --- a/web/src/less/signin.less +++ b/web/src/less/signin.less @@ -69,7 +69,7 @@ > .tip-text { @apply w-auto inline-block float-right text-sm mt-4 text-gray-500 text-right whitespace-pre-wrap; - &.owner-tip { + &.host-tip { @apply bg-blue-500 text-white px-2 py-1 rounded; } } diff --git a/web/src/pages/Signin.tsx b/web/src/pages/Signin.tsx index 2781419b..c4d6806e 100644 --- a/web/src/pages/Signin.tsx +++ b/web/src/pages/Signin.tsx @@ -17,7 +17,7 @@ const validateConfig: ValidatorConfig = { const Signin: React.FC = () => { const pageLoadingState = useLoading(true); - const [siteOwner, setSiteOwner] = useState(); + const [siteHost, setSiteHost] = useState(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const actionBtnLoadingState = useLoading(false); @@ -25,7 +25,7 @@ const Signin: React.FC = () => { useEffect(() => { api.getSystemStatus().then(({ data }) => { const { data: status } = data; - setSiteOwner(status.owner); + setSiteHost(status.host); if (status.profile.mode === "dev") { setEmail("demo@usememos.com"); setPassword("secret"); @@ -77,7 +77,7 @@ const Signin: React.FC = () => { actionBtnLoadingState.setFinish(); }; - const handleSignUpAsOwnerBtnsClick = async () => { + const handleSignUpAsHostBtnsClick = async () => { if (actionBtnLoadingState.isLoading) { return; } @@ -96,7 +96,7 @@ const Signin: React.FC = () => { try { actionBtnLoadingState.setLoading(); - await api.signup(email, password, "OWNER"); + await api.signup(email, password, "HOST"); const user = await userService.doSignIn(); if (user) { locationService.replaceHistory("/"); @@ -132,7 +132,7 @@ const Signin: React.FC = () => {
- {siteOwner || pageLoadingState.isLoading ? ( + {siteHost || pageLoadingState.isLoading ? ( )}
-

- {siteOwner || pageLoadingState.isLoading - ? "If you don't have an account, please\ncontact the site owner." - : "You are registering as the Site Owner."} +

+ {siteHost || pageLoadingState.isLoading + ? "If you don't have an account, please\ncontact the site host." + : "You are registering as the Site Host."}

diff --git a/web/src/types/modules/system.d.ts b/web/src/types/modules/system.d.ts index 2f5195e8..f2a6dd10 100644 --- a/web/src/types/modules/system.d.ts +++ b/web/src/types/modules/system.d.ts @@ -4,6 +4,6 @@ interface Profile { } interface SystemStatus { - owner: User; + host: User; profile: Profile; } diff --git a/web/src/types/modules/user.d.ts b/web/src/types/modules/user.d.ts index 05813709..7403dabc 100644 --- a/web/src/types/modules/user.d.ts +++ b/web/src/types/modules/user.d.ts @@ -1,5 +1,5 @@ type UserId = number; -type UserRole = "OWNER" | "USER"; +type UserRole = "HOST" | "USER"; interface User { id: UserId;