chore: upgrade version to 0.11.0 (#1143)

* chore: upgrade version to `0.11.0`

* chore: update
This commit is contained in:
boojack 2023-02-24 08:31:54 +08:00 committed by GitHub
parent 9c5b44d070
commit cc23d5cafe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 81 additions and 26 deletions

View file

@ -157,6 +157,21 @@ func (s *Server) registerSystemRoutes(g *echo.Group) {
g.GET("/system/setting", func(c echo.Context) error { g.GET("/system/setting", func(c echo.Context) error {
ctx := c.Request().Context() ctx := c.Request().Context()
userID, ok := c.Get(getUserIDContextKey()).(int)
if !ok {
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
}
user, err := s.Store.FindUser(ctx, &api.UserFind{
ID: &userID,
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
}
if user == nil || user.Role != api.Host {
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
}
systemSettingList, err := s.Store.FindSystemSettingList(ctx, &api.SystemSettingFind{}) systemSettingList, err := s.Store.FindSystemSettingList(ctx, &api.SystemSettingFind{})
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find system setting list").SetInternal(err) return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find system setting list").SetInternal(err)
@ -170,6 +185,7 @@ func (s *Server) registerSystemRoutes(g *echo.Group) {
if !ok { if !ok {
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session") return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
} }
user, err := s.Store.FindUser(ctx, &api.UserFind{ user, err := s.Store.FindUser(ctx, &api.UserFind{
ID: &userID, ID: &userID,
}) })
@ -179,6 +195,7 @@ func (s *Server) registerSystemRoutes(g *echo.Group) {
if user == nil || user.Role != api.Host { if user == nil || user.Role != api.Host {
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized") return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
} }
if err := s.Store.Vacuum(ctx); err != nil { if err := s.Store.Vacuum(ctx); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to vacuum database").SetInternal(err) return echo.NewHTTPError(http.StatusInternalServerError, "Failed to vacuum database").SetInternal(err)
} }

View file

@ -9,10 +9,10 @@ import (
// Version is the service current released version. // Version is the service current released version.
// Semantic versioning: https://semver.org/ // Semantic versioning: https://semver.org/
var Version = "0.10.3" var Version = "0.11.0"
// DevVersion is the service current development version. // DevVersion is the service current development version.
var DevVersion = "0.10.3" var DevVersion = "0.11.0"
func GetCurrentVersion(mode string) string { func GetCurrentVersion(mode string) string {
if mode == "dev" || mode == "demo" { if mode == "dev" || mode == "demo" {

View file

@ -0,0 +1,4 @@
ALTER TABLE
user
ADD
COLUMN avatar_url TEXT NOT NULL DEFAULT '';

View file

@ -0,0 +1,8 @@
-- idp
CREATE TABLE idp (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type TEXT NOT NULL,
identifier_filter TEXT NOT NULL DEFAULT '',
config TEXT NOT NULL DEFAULT '{}'
);

View file

@ -0,0 +1,7 @@
-- storage
CREATE TABLE storage (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type TEXT NOT NULL,
config TEXT NOT NULL DEFAULT '{}'
);

View file

@ -23,7 +23,8 @@ CREATE TABLE user (
email TEXT NOT NULL DEFAULT '', email TEXT NOT NULL DEFAULT '',
nickname TEXT NOT NULL DEFAULT '', nickname TEXT NOT NULL DEFAULT '',
password_hash TEXT NOT NULL, password_hash TEXT NOT NULL,
open_id TEXT NOT NULL UNIQUE open_id TEXT NOT NULL UNIQUE,
avatar_url TEXT NOT NULL DEFAULT ''
); );
-- user_setting -- user_setting
@ -102,4 +103,21 @@ CREATE TABLE activity (
type TEXT NOT NULL DEFAULT '', type TEXT NOT NULL DEFAULT '',
level TEXT NOT NULL CHECK (level IN ('INFO', 'WARN', 'ERROR')) DEFAULT 'INFO', level TEXT NOT NULL CHECK (level IN ('INFO', 'WARN', 'ERROR')) DEFAULT 'INFO',
payload TEXT NOT NULL DEFAULT '{}' payload TEXT NOT NULL DEFAULT '{}'
);
-- storage
CREATE TABLE storage (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type TEXT NOT NULL,
config TEXT NOT NULL DEFAULT '{}'
);
-- idp
CREATE TABLE idp (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type TEXT NOT NULL,
identifier_filter TEXT NOT NULL DEFAULT '',
config TEXT NOT NULL DEFAULT '{}'
); );

View file

@ -1,5 +1,4 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { Button, Input, Typography } from "@mui/joy"; import { Button, Input, Typography } from "@mui/joy";
import * as api from "../helpers/api"; import * as api from "../helpers/api";
import { generateDialog } from "./Dialog"; import { generateDialog } from "./Dialog";
@ -13,7 +12,6 @@ interface Props extends DialogProps {
const CreateStorageServiceDialog: React.FC<Props> = (props: Props) => { const CreateStorageServiceDialog: React.FC<Props> = (props: Props) => {
const { destroy, storage, confirmCallback } = props; const { destroy, storage, confirmCallback } = props;
const { t } = useTranslation();
const [basicInfo, setBasicInfo] = useState({ const [basicInfo, setBasicInfo] = useState({
name: "", name: "",
}); });
@ -95,9 +93,18 @@ const CreateStorageServiceDialog: React.FC<Props> = (props: Props) => {
return ( return (
<> <>
<div className="dialog-header-container !w-64"> <div className="dialog-header-container">
<p className="title-text"> <p className="title-text">
{isCreating ? t("setting.storage-section.create-a-service") : t("setting.storage-section.update-a-service")} {isCreating ? "Create storage" : "Update storage"}
<a
className="ml-2 text-sm text-blue-600 hover:opacity-80 hover:underline"
href="https://usememos.com/docs/storage"
target="_blank"
rel="noreferrer"
>
Learn more
<Icon.ExternalLink className="inline -mt-1 ml-1 w-4 h-auto opacity-80" />
</a>
</p> </p>
<button className="btn close-btn" onClick={handleCloseBtnClick}> <button className="btn close-btn" onClick={handleCloseBtnClick}>
<Icon.X /> <Icon.X />
@ -106,7 +113,6 @@ const CreateStorageServiceDialog: React.FC<Props> = (props: Props) => {
<div className="dialog-content-container"> <div className="dialog-content-container">
<Typography className="!mb-1" level="body2"> <Typography className="!mb-1" level="body2">
Name Name
<span className="text-sm text-gray-400 ml-1">(Unique identifier)</span>
</Typography> </Typography>
<Input <Input
className="mb-2" className="mb-2"

View file

@ -1,7 +1,7 @@
import { Option, Select } from "@mui/joy"; import { Option, Select } from "@mui/joy";
import { useState } from "react"; import { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useGlobalStore, useUserStore } from "../store/module"; import { useUserStore } from "../store/module";
import Icon from "./Icon"; import Icon from "./Icon";
import { generateDialog } from "./Dialog"; import { generateDialog } from "./Dialog";
import BetaBadge from "./BetaBadge"; import BetaBadge from "./BetaBadge";
@ -24,7 +24,6 @@ interface State {
const SettingDialog: React.FC<Props> = (props: Props) => { const SettingDialog: React.FC<Props> = (props: Props) => {
const { destroy } = props; const { destroy } = props;
const { t } = useTranslation(); const { t } = useTranslation();
const globalStore = useGlobalStore();
const userStore = useUserStore(); const userStore = useUserStore();
const user = userStore.state.user; const user = userStore.state.user;
const [state, setState] = useState<State>({ const [state, setState] = useState<State>({
@ -83,22 +82,18 @@ const SettingDialog: React.FC<Props> = (props: Props) => {
> >
<Icon.Settings2 className="w-4 h-auto mr-2 opacity-80" /> {t("setting.system")} <Icon.Settings2 className="w-4 h-auto mr-2 opacity-80" /> {t("setting.system")}
</span> </span>
{globalStore.isDev() && ( <span
<span onClick={() => handleSectionSelectorItemClick("storage")}
onClick={() => handleSectionSelectorItemClick("storage")} className={`section-item ${state.selectedSection === "storage" ? "selected" : ""}`}
className={`section-item ${state.selectedSection === "storage" ? "selected" : ""}`} >
> <Icon.Database className="w-4 h-auto mr-2 opacity-80" /> {t("setting.storage")} <BetaBadge />
<Icon.Database className="w-4 h-auto mr-2 opacity-80" /> {t("setting.storage")} <BetaBadge /> </span>
</span> <span
)} onClick={() => handleSectionSelectorItemClick("sso")}
{globalStore.isDev() && ( className={`section-item ${state.selectedSection === "sso" ? "selected" : ""}`}
<span >
onClick={() => handleSectionSelectorItemClick("sso")} <Icon.Key className="w-4 h-auto mr-2 opacity-80" /> {t("setting.sso")} <BetaBadge />
className={`section-item ${state.selectedSection === "sso" ? "selected" : ""}`} </span>
>
<Icon.Key className="w-4 h-auto mr-2 opacity-80" /> {t("setting.sso")} <BetaBadge />
</span>
)}
</div> </div>
</> </>
) : null} ) : null}