chore: update workspace service

This commit is contained in:
Steven 2024-03-21 21:39:34 +08:00
parent 1d83c68cb5
commit 18d16abdb5
16 changed files with 121 additions and 89 deletions

View File

@ -14,18 +14,21 @@ service WorkspaceService {
} }
message WorkspaceProfile { message WorkspaceProfile {
// The name of intance owner.
// Format: "users/{id}"
string owner = 1;
// version is the current version of instance // version is the current version of instance
string version = 1; string version = 2;
// mode is the instance mode (e.g. "prod", "dev" or "demo"). // mode is the instance mode (e.g. "prod", "dev" or "demo").
string mode = 2; string mode = 3;
// allow_registration is whether the registration is allowed. // disallow_signup is whether the signup is disallowed.
bool allow_registration = 3; bool disallow_signup = 4;
// allow_password_login is whether the password login is allowed. // disable_password_login is whether the password login is disabled.
bool disable_password_login = 4; bool disable_password_login = 5;
// additional_script is the additional script. // additional_script is the additional script.
string additional_script = 5; string additional_script = 6;
// additional_style is the additional style. // additional_style is the additional style.
string additional_style = 6; string additional_style = 7;
} }
message GetWorkspaceProfileRequest {} message GetWorkspaceProfileRequest {}

View File

@ -2600,10 +2600,11 @@ Used internally for obfuscating the page token.
| Field | Type | Label | Description | | Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- | | ----- | ---- | ----- | ----------- |
| owner | [string](#string) | | The name of intance owner. Format: "users/{id}" |
| version | [string](#string) | | version is the current version of instance | | version | [string](#string) | | version is the current version of instance |
| mode | [string](#string) | | mode is the instance mode (e.g. "prod", "dev" or "demo"). | | mode | [string](#string) | | mode is the instance mode (e.g. "prod", "dev" or "demo"). |
| allow_registration | [bool](#bool) | | allow_registration is whether the registration is allowed. | | disallow_signup | [bool](#bool) | | disallow_signup is whether the signup is disallowed. |
| disable_password_login | [bool](#bool) | | allow_password_login is whether the password login is allowed. | | disable_password_login | [bool](#bool) | | disable_password_login is whether the password login is disabled. |
| additional_script | [string](#string) | | additional_script is the additional script. | | additional_script | [string](#string) | | additional_script is the additional script. |
| additional_style | [string](#string) | | additional_style is the additional style. | | additional_style | [string](#string) | | additional_style is the additional style. |

View File

@ -26,18 +26,21 @@ type WorkspaceProfile struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
// The name of intance owner.
// Format: "users/{id}"
Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty"`
// version is the current version of instance // version is the current version of instance
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
// mode is the instance mode (e.g. "prod", "dev" or "demo"). // mode is the instance mode (e.g. "prod", "dev" or "demo").
Mode string `protobuf:"bytes,2,opt,name=mode,proto3" json:"mode,omitempty"` Mode string `protobuf:"bytes,3,opt,name=mode,proto3" json:"mode,omitempty"`
// allow_registration is whether the registration is allowed. // disallow_signup is whether the signup is disallowed.
AllowRegistration bool `protobuf:"varint,3,opt,name=allow_registration,json=allowRegistration,proto3" json:"allow_registration,omitempty"` DisallowSignup bool `protobuf:"varint,4,opt,name=disallow_signup,json=disallowSignup,proto3" json:"disallow_signup,omitempty"`
// allow_password_login is whether the password login is allowed. // disable_password_login is whether the password login is disabled.
DisablePasswordLogin bool `protobuf:"varint,4,opt,name=disable_password_login,json=disablePasswordLogin,proto3" json:"disable_password_login,omitempty"` DisablePasswordLogin bool `protobuf:"varint,5,opt,name=disable_password_login,json=disablePasswordLogin,proto3" json:"disable_password_login,omitempty"`
// additional_script is the additional script. // additional_script is the additional script.
AdditionalScript string `protobuf:"bytes,5,opt,name=additional_script,json=additionalScript,proto3" json:"additional_script,omitempty"` AdditionalScript string `protobuf:"bytes,6,opt,name=additional_script,json=additionalScript,proto3" json:"additional_script,omitempty"`
// additional_style is the additional style. // additional_style is the additional style.
AdditionalStyle string `protobuf:"bytes,6,opt,name=additional_style,json=additionalStyle,proto3" json:"additional_style,omitempty"` AdditionalStyle string `protobuf:"bytes,7,opt,name=additional_style,json=additionalStyle,proto3" json:"additional_style,omitempty"`
} }
func (x *WorkspaceProfile) Reset() { func (x *WorkspaceProfile) Reset() {
@ -72,6 +75,13 @@ func (*WorkspaceProfile) Descriptor() ([]byte, []int) {
return file_api_v2_workspace_service_proto_rawDescGZIP(), []int{0} return file_api_v2_workspace_service_proto_rawDescGZIP(), []int{0}
} }
func (x *WorkspaceProfile) GetOwner() string {
if x != nil {
return x.Owner
}
return ""
}
func (x *WorkspaceProfile) GetVersion() string { func (x *WorkspaceProfile) GetVersion() string {
if x != nil { if x != nil {
return x.Version return x.Version
@ -86,9 +96,9 @@ func (x *WorkspaceProfile) GetMode() string {
return "" return ""
} }
func (x *WorkspaceProfile) GetAllowRegistration() bool { func (x *WorkspaceProfile) GetDisallowSignup() bool {
if x != nil { if x != nil {
return x.AllowRegistration return x.DisallowSignup
} }
return false return false
} }
@ -206,22 +216,23 @@ var file_api_v2_workspace_service_proto_rawDesc = []byte{
0x63, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x1c, 0x12, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x1c,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfd, 0x01, 0x0a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x02, 0x0a,
0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x2d, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x61, 0x6c, 0x6c, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x6c, 0x6c, 0x6f,
0x6f, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x77, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e,
0x64, 0x69, 0x73, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x34,
0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f,
0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14,
0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x4c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x4c,
0x6f, 0x67, 0x69, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,
0x61, 0x6c, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x61, 0x6c, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
0x10, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x63, 0x72, 0x69, 0x70, 0x10, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x63, 0x72, 0x69, 0x70,
0x74, 0x12, 0x29, 0x0a, 0x10, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f,
0x73, 0x74, 0x79, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x64, 0x64, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x64, 0x64,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x22, 0x1c, 0x0a, 0x1a,
0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66,
0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6a, 0x0a, 0x1b, 0x47, 0x65, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6a, 0x0a, 0x1b, 0x47, 0x65,

View File

@ -1857,9 +1857,10 @@ GetActivity returns the activity with the given id.
| Name | Type | Description | Required | | Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- | | ---- | ---- | ----------- | -------- |
| owner | string | | No |
| version | string | | No | | version | string | | No |
| mode | string | mode is the instance mode (e.g. "prod", "dev" or "demo"). | No | | mode | string | mode is the instance mode (e.g. "prod", "dev" or "demo"). | No |
| allowRegistration | boolean | allow_registration is whether the registration is allowed. | No | | disallowSignup | boolean | disallow_signup is whether the signup is disallowed. | No |
| disablePasswordLogin | boolean | allow_password_login is whether the password login is allowed. | No | | disablePasswordLogin | boolean | disable_password_login is whether the password login is disabled. | No |
| additionalScript | string | additional_script is the additional script. | No | | additionalScript | string | additional_script is the additional script. | No |
| additionalStyle | string | additional_style is the additional style. | No | | additionalStyle | string | additional_style is the additional style. | No |

View File

@ -2346,18 +2346,23 @@ definitions:
v2WorkspaceProfile: v2WorkspaceProfile:
type: object type: object
properties: properties:
owner:
type: string
title: |-
The name of intance owner.
Format: "users/{id}"
version: version:
type: string type: string
title: version is the current version of instance title: version is the current version of instance
mode: mode:
type: string type: string
description: mode is the instance mode (e.g. "prod", "dev" or "demo"). description: mode is the instance mode (e.g. "prod", "dev" or "demo").
allowRegistration: disallowSignup:
type: boolean type: boolean
description: allow_registration is whether the registration is allowed. description: disallow_signup is whether the signup is disallowed.
disablePasswordLogin: disablePasswordLogin:
type: boolean type: boolean
description: allow_password_login is whether the password login is allowed. description: disable_password_login is whether the password login is disabled.
additionalScript: additionalScript:
type: string type: string
description: additional_script is the additional script. description: additional_script is the additional script.

View File

@ -3,15 +3,56 @@ package v2
import ( import (
"context" "context"
"github.com/pkg/errors"
apiv2pb "github.com/usememos/memos/proto/gen/api/v2" apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
"github.com/usememos/memos/store"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
) )
func (s *APIV2Service) GetWorkspaceProfile(_ context.Context, _ *apiv2pb.GetWorkspaceProfileRequest) (*apiv2pb.GetWorkspaceProfileResponse, error) { var owner *apiv2pb.User = nil
func (s *APIV2Service) GetWorkspaceProfile(ctx context.Context, _ *apiv2pb.GetWorkspaceProfileRequest) (*apiv2pb.GetWorkspaceProfileResponse, error) {
workspaceProfile := &apiv2pb.WorkspaceProfile{ workspaceProfile := &apiv2pb.WorkspaceProfile{
Version: s.Profile.Version, Version: s.Profile.Version,
Mode: s.Profile.Mode, Mode: s.Profile.Mode,
} }
owner, err := s.GetInstanceOwner(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get instance owner: %v", err)
}
if owner != nil {
workspaceProfile.Owner = owner.Name
}
generalSetting, err := s.Store.GetWorkspaceGeneralSetting(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get workspace general setting: %v", err)
}
workspaceProfile.DisallowSignup = generalSetting.DisallowSignup
workspaceProfile.DisablePasswordLogin = generalSetting.DisallowPasswordLogin
workspaceProfile.AdditionalStyle = generalSetting.AdditionalStyle
workspaceProfile.AdditionalScript = generalSetting.AdditionalScript
return &apiv2pb.GetWorkspaceProfileResponse{ return &apiv2pb.GetWorkspaceProfileResponse{
WorkspaceProfile: workspaceProfile, WorkspaceProfile: workspaceProfile,
}, nil }, nil
} }
func (s *APIV2Service) GetInstanceOwner(ctx context.Context) (*apiv2pb.User, error) {
if owner != nil {
return owner, nil
}
hostUserType := store.RoleHost
user, err := s.Store.GetUser(ctx, &store.FindUser{
Role: &hostUserType,
})
if err != nil {
return nil, errors.Wrapf(err, "failed to find owner")
}
if user == nil {
return nil, errors.New("owner not found")
}
owner = convertUserFromStore(user)
return owner, nil
}

View File

@ -16,7 +16,7 @@ const App = () => {
const globalStore = useGlobalStore(); const globalStore = useGlobalStore();
const workspaceSettingStore = useWorkspaceSettingStore(); const workspaceSettingStore = useWorkspaceSettingStore();
const userStore = useUserStore(); const userStore = useUserStore();
const { appearance, locale, systemStatus } = globalStore.state; const { appearance, locale, systemStatus, workspaceProfile } = globalStore.state;
const userSetting = userStore.userSetting; const userSetting = userStore.userSetting;
const workspaceGeneralSetting = const workspaceGeneralSetting =
workspaceSettingStore.getWorkspaceSettingByKey(WorkspaceSettingKey.WORKSPACE_SETTING_GENERAL).generalSetting || workspaceSettingStore.getWorkspaceSettingByKey(WorkspaceSettingKey.WORKSPACE_SETTING_GENERAL).generalSetting ||
@ -24,10 +24,10 @@ const App = () => {
// Redirect to sign up page if no host. // Redirect to sign up page if no host.
useEffect(() => { useEffect(() => {
if (!systemStatus.host) { if (!workspaceProfile.owner) {
navigateTo("/auth/signup"); navigateTo("/auth/signup");
} }
}, [systemStatus.host]); }, [workspaceProfile.owner]);
useEffect(() => { useEffect(() => {
const darkMediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); const darkMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");

View File

@ -15,7 +15,7 @@ const ChangePasswordDialog: React.FC<Props> = ({ destroy }: Props) => {
const currentUser = useCurrentUser(); const currentUser = useCurrentUser();
const userStore = useUserStore(); const userStore = useUserStore();
const globalStore = useGlobalStore(); const globalStore = useGlobalStore();
const profile = globalStore.state.systemStatus.profile; const profile = globalStore.state.workspaceProfile;
const [newPassword, setNewPassword] = useState(""); const [newPassword, setNewPassword] = useState("");
const [newPasswordAgain, setNewPasswordAgain] = useState(""); const [newPasswordAgain, setNewPasswordAgain] = useState("");

View File

@ -3,24 +3,14 @@ import { useEffect, useState } from "react";
import { toast } from "react-hot-toast"; import { toast } from "react-hot-toast";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import * as api from "@/helpers/api"; import * as api from "@/helpers/api";
import { useGlobalStore } from "@/store/module";
import { useTranslate } from "@/utils/i18n"; import { useTranslate } from "@/utils/i18n";
import showCreateIdentityProviderDialog from "../CreateIdentityProviderDialog"; import showCreateIdentityProviderDialog from "../CreateIdentityProviderDialog";
import { showCommonDialog } from "../Dialog/CommonDialog"; import { showCommonDialog } from "../Dialog/CommonDialog";
import Icon from "../Icon"; import Icon from "../Icon";
import LearnMore from "../LearnMore"; import LearnMore from "../LearnMore";
interface State {
disablePasswordLogin: boolean;
}
const SSOSection = () => { const SSOSection = () => {
const t = useTranslate(); const t = useTranslate();
const globalStore = useGlobalStore();
const systemStatus = globalStore.state.systemStatus;
const [state] = useState<State>({
disablePasswordLogin: systemStatus.disablePasswordLogin,
});
const [identityProviderList, setIdentityProviderList] = useState<IdentityProvider[]>([]); const [identityProviderList, setIdentityProviderList] = useState<IdentityProvider[]>([]);
useEffect(() => { useEffect(() => {
@ -33,11 +23,7 @@ const SSOSection = () => {
}; };
const handleDeleteIdentityProvider = async (identityProvider: IdentityProvider) => { const handleDeleteIdentityProvider = async (identityProvider: IdentityProvider) => {
let content = t("setting.sso-section.confirm-delete", { name: identityProvider.name }); const content = t("setting.sso-section.confirm-delete", { name: identityProvider.name });
if (state.disablePasswordLogin) {
content += "\n\n" + t("setting.sso-section.disabled-password-login-warning");
}
showCommonDialog({ showCommonDialog({
title: t("setting.sso-section.delete-sso"), title: t("setting.sso-section.delete-sso"),

View File

@ -88,7 +88,7 @@ const Setting = () => {
onClick={() => handleSectionSelectorItemClick(item)} onClick={() => handleSectionSelectorItemClick(item)}
/> />
))} ))}
<span className="px-3 mt-2 opacity-70 text-sm">Version: v{globalStore.state.systemStatus.profile.version}</span> <span className="px-3 mt-2 opacity-70 text-sm">Version: v{globalStore.state.workspaceProfile.version}</span>
</div> </div>
</> </>
) : null} ) : null}

View File

@ -23,8 +23,7 @@ const SignIn = () => {
const workspaceSettingStore = useWorkspaceSettingStore(); const workspaceSettingStore = useWorkspaceSettingStore();
const userStore = useUserStore(); const userStore = useUserStore();
const actionBtnLoadingState = useLoading(false); const actionBtnLoadingState = useLoading(false);
const { appearance, locale, systemStatus } = globalStore.state; const { appearance, locale, systemStatus, workspaceProfile } = globalStore.state;
const mode = systemStatus.profile.mode;
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const [remember, setRemember] = useState(true); const [remember, setRemember] = useState(true);
@ -42,11 +41,11 @@ const SignIn = () => {
}, []); }, []);
useEffect(() => { useEffect(() => {
if (mode === "demo") { if (workspaceProfile.mode === "demo") {
setUsername("memos-demo"); setUsername("memos-demo");
setPassword("secret"); setPassword("secret");
} }
}, [mode]); }, [workspaceProfile.mode]);
const handleUsernameInputChanged = (e: React.ChangeEvent<HTMLInputElement>) => { const handleUsernameInputChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
const text = e.target.value as string; const text = e.target.value as string;

View File

@ -17,7 +17,7 @@ const SignUp = () => {
const globalStore = useGlobalStore(); const globalStore = useGlobalStore();
const userStore = useUserStore(); const userStore = useUserStore();
const actionBtnLoadingState = useLoading(false); const actionBtnLoadingState = useLoading(false);
const { appearance, locale, systemStatus } = globalStore.state; const { appearance, locale, systemStatus, workspaceProfile } = globalStore.state;
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
@ -119,7 +119,7 @@ const SignUp = () => {
</Button> </Button>
</div> </div>
</form> </form>
{!systemStatus.host && <p className="w-full mt-4 text-sm font-medium dark:text-gray-500">{t("auth.host-tip")}</p>} {!workspaceProfile.owner && <p className="w-full mt-4 text-sm font-medium dark:text-gray-500">{t("auth.host-tip")}</p>}
<p className="w-full mt-4 text-sm"> <p className="w-full mt-4 text-sm">
<span className="dark:text-gray-500">{t("auth.sign-in-tip")}</span> <span className="dark:text-gray-500">{t("auth.sign-in-tip")}</span>
<Link to="/auth" className="cursor-pointer ml-2 text-blue-600 hover:underline" unstable_viewTransition> <Link to="/auth" className="cursor-pointer ml-2 text-blue-600 hover:underline" unstable_viewTransition>

View File

@ -1,6 +1,8 @@
import { workspaceServiceClient } from "@/grpcweb";
import * as api from "@/helpers/api"; import * as api from "@/helpers/api";
import storage from "@/helpers/storage"; import storage from "@/helpers/storage";
import i18n from "@/i18n"; import i18n from "@/i18n";
import { WorkspaceProfile } from "@/types/proto/api/v2/workspace_service";
import { findNearestMatchedLanguage } from "@/utils/i18n"; import { findNearestMatchedLanguage } from "@/utils/i18n";
import store, { useAppSelector } from "../"; import store, { useAppSelector } from "../";
import { setAppearance, setGlobalState, setLocale } from "../reducer/global"; import { setAppearance, setGlobalState, setLocale } from "../reducer/global";
@ -22,8 +24,14 @@ export const initialGlobalState = async () => {
appearance: "system", appearance: "system",
}, },
} as SystemStatus, } as SystemStatus,
workspaceProfile: WorkspaceProfile.fromPartial({}),
}; };
const { workspaceProfile } = await workspaceServiceClient.getWorkspaceProfile({});
if (workspaceProfile) {
defaultGlobalState.workspaceProfile = workspaceProfile;
}
const { data } = await api.getSystemStatus(); const { data } = await api.getSystemStatus();
if (data) { if (data) {
const customizedProfile = data.customizedProfile; const customizedProfile = data.customizedProfile;
@ -62,7 +70,7 @@ export const useGlobalStore = () => {
return store.getState().global.systemStatus.disablePublicMemos; return store.getState().global.systemStatus.disablePublicMemos;
}, },
isDev: () => { isDev: () => {
return state.systemStatus.profile.mode !== "prod"; return state.workspaceProfile.mode !== "prod";
}, },
fetchSystemStatus: async () => { fetchSystemStatus: async () => {
const { data: systemStatus } = await api.getSystemStatus(); const { data: systemStatus } = await api.getSystemStatus();

View File

@ -1,9 +1,11 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit"; import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { WorkspaceProfile } from "@/types/proto/api/v2/workspace_service";
interface State { interface State {
locale: Locale; locale: Locale;
appearance: Appearance; appearance: Appearance;
systemStatus: SystemStatus; systemStatus: SystemStatus;
workspaceProfile: WorkspaceProfile;
} }
const globalSlice = createSlice({ const globalSlice = createSlice({
@ -12,11 +14,6 @@ const globalSlice = createSlice({
locale: "en", locale: "en",
appearance: "system", appearance: "system",
systemStatus: { systemStatus: {
host: undefined,
profile: {
mode: "demo",
version: "",
},
disablePasswordLogin: false, disablePasswordLogin: false,
disablePublicMemos: false, disablePublicMemos: false,
memoDisplayWithUpdatedTs: false, memoDisplayWithUpdatedTs: false,
@ -28,6 +25,7 @@ const globalSlice = createSlice({
appearance: "system", appearance: "system",
}, },
}, },
workspaceProfile: WorkspaceProfile.fromPartial({}),
} as State, } as State,
reducers: { reducers: {
setGlobalState: (state, action: PayloadAction<Partial<State>>) => { setGlobalState: (state, action: PayloadAction<Partial<State>>) => {

View File

@ -1,8 +1,3 @@
interface Profile {
mode: string;
version: string;
}
interface CustomizedProfile { interface CustomizedProfile {
name: string; name: string;
logoUrl: string; logoUrl: string;
@ -12,8 +7,6 @@ interface CustomizedProfile {
} }
interface SystemStatus { interface SystemStatus {
host?: User;
profile: Profile;
// System settings // System settings
disablePasswordLogin: boolean; disablePasswordLogin: boolean;
disablePublicMemos: boolean; disablePublicMemos: boolean;

View File

@ -1,14 +0,0 @@
type UserRole = "HOST" | "USER";
interface User {
id: number;
createdTs: number;
updatedTs: number;
username: string;
role: UserRole;
email: string;
nickname: string;
avatarUrl: string;
}