diff --git a/app/src/config/editor.ts b/app/src/config/editor.ts index 851b2c65e..102acc26f 100644 --- a/app/src/config/editor.ts +++ b/app/src/config/editor.ts @@ -310,10 +310,12 @@ export const editor = { if (fontFamilyElement.tagName === "SELECT") { let fontFamilyHTML = ``; fetchPost("/api/system/getSysFonts", {}, (response) => { - response.data.forEach((item: string) => { - fontFamilyHTML += ``; - }); - fontFamilyElement.innerHTML = fontFamilyHTML; + if (response.code === 0) { + response.data.forEach((item: string) => { + fontFamilyHTML += ``; + }); + fontFamilyElement.innerHTML = fontFamilyHTML; + } }); } editor.element.querySelector("#clearHistory").addEventListener("click", () => { diff --git a/app/src/index.ts b/app/src/index.ts index 0bcd88cf5..c666a0cc1 100644 --- a/app/src/index.ts +++ b/app/src/index.ts @@ -38,6 +38,8 @@ export class App { registerServiceWorker(`${Constants.SERVICE_WORKER_PATH}?v=${Constants.SIYUAN_VERSION}`); /// #endif addBaseURL(); + addScriptSync(`${Constants.PROTYLE_CDN}/js/lute/lute.min.js?v=${Constants.SIYUAN_VERSION}`, "protyleLuteScript"), + addScript(`${Constants.PROTYLE_CDN}/js/protyle-html.js?v=${Constants.SIYUAN_VERSION}`, "protyleWcHtmlScript"), this.appId = Constants.SIYUAN_APPID; window.siyuan = { @@ -158,24 +160,40 @@ export class App { }; fetchPost("/api/system/getConf", {}, async (response) => { - addScriptSync(`${Constants.PROTYLE_CDN}/js/lute/lute.min.js?v=${Constants.SIYUAN_VERSION}`, "protyleLuteScript"); - addScript(`${Constants.PROTYLE_CDN}/js/protyle-html.js?v=${Constants.SIYUAN_VERSION}`, "protyleWcHtmlScript"); window.siyuan.config = response.data.conf; - await loadPlugins(this); - getLocalStorage(() => { - fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages: IObject) => { - window.siyuan.languages = lauguages; - window.siyuan.menus = new Menus(this); - bootSync(); + + const promises = [ + loadPlugins(this), + new Promise(resolve => getLocalStorage(resolve)), + new Promise(resolve => fetchGet( + `/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, + (lauguages: IObject) => { + window.siyuan.languages = lauguages; + resolve(); + }, + )), + ]; + + if (!window.siyuan.config.readonly) { + promises.push(new Promise(resolve => { fetchPost("/api/setting/getCloudUser", {}, userResponse => { window.siyuan.user = userResponse.data; - onGetConfig(response.data.start, this); - account.onSetaccount(); - setTitle(window.siyuan.languages.siyuanNote); - initMessage(); + resolve(); }); - }); - }); + })); + } + + await Promise.all(promises); + + if (!window.siyuan.config.readonly) { + bootSync(); + } + + window.siyuan.menus = new Menus(this); + onGetConfig(response.data.start, this); + account.onSetaccount(); + setTitle(window.siyuan.languages.siyuanNote); + initMessage(); }); setNoteBook(); initBlockPopover(this); diff --git a/app/src/layout/Wnd.ts b/app/src/layout/Wnd.ts index 1bee1396b..a2fd12273 100644 --- a/app/src/layout/Wnd.ts +++ b/app/src/layout/Wnd.ts @@ -105,7 +105,7 @@ export class Wnd { this.headersElement.parentElement.addEventListener("click", (event) => { let target = event.target as HTMLElement; while (target && !target.isEqualNode(this.headersElement)) { - if (target.classList.contains("block__icon") && target.getAttribute("data-type") === "new") { + if (target.classList.contains("block__icon") && target.getAttribute("data-type") === "new" && !window.siyuan.config.readonly) { setPanelFocus(this.headersElement.parentElement.parentElement); newFile({ app, diff --git a/app/src/layout/status.ts b/app/src/layout/status.ts index 1cd7399b2..bd7d048af 100644 --- a/app/src/layout/status.ts +++ b/app/src/layout/status.ts @@ -68,6 +68,7 @@ export const initStatus = (isWindow = false) => { window.siyuan.menus.menu.append(new MenuItem({ label: window.siyuan.languages.userGuide, icon: "iconHelp", + disabled: window.siyuan.config.readonly, click: () => { mountHelp(); } diff --git a/app/src/layout/topBar.ts b/app/src/layout/topBar.ts index 64a01139e..152e28d4f 100644 --- a/app/src/layout/topBar.ts +++ b/app/src/layout/topBar.ts @@ -305,6 +305,7 @@ const openPlugin = (app: App, target: Element) => { menu.addItem({ icon: "iconSettings", label: window.siyuan.languages.manage, + disabled: window.siyuan.config.readonly, click() { openSetting(app).element.querySelector('.b3-tab-bar [data-name="bazaar"]').dispatchEvent(new CustomEvent("click")); } @@ -374,7 +375,7 @@ const openPlugin = (app: App, target: Element) => { } }); if (!hasPlugin) { - window.siyuan.menus.menu.element.querySelector(".b3-menu__separator").remove(); + window.siyuan.menus.menu.element.querySelector(".b3-menu__separator")?.remove(); } let rect = target.getBoundingClientRect(); if (rect.width === 0) { diff --git a/app/src/menus/commonMenuItem.ts b/app/src/menus/commonMenuItem.ts index 0c45f0272..e571f3498 100644 --- a/app/src/menus/commonMenuItem.ts +++ b/app/src/menus/commonMenuItem.ts @@ -448,6 +448,7 @@ export const exportMd = (id: string) => { label: window.siyuan.languages.template, iconClass: "ft__error", icon: "iconMarkdown", + disabled: window.siyuan.config.readonly, click: async () => { const result = await fetchSyncPost("/api/block/getRefText", {id: id}); @@ -507,8 +508,9 @@ export const exportMd = (id: string) => { }); }); return; + } else if (response.code === 0) { + showMessage(window.siyuan.languages.exportTplSucc); } - showMessage(window.siyuan.languages.exportTplSucc); }); dialog.destroy(); }); diff --git a/app/src/menus/workspace.ts b/app/src/menus/workspace.ts index 85796b268..88f6d2017 100644 --- a/app/src/menus/workspace.ts +++ b/app/src/menus/workspace.ts @@ -440,6 +440,7 @@ export const workspaceMenu = (app: App, rect: DOMRect) => { window.siyuan.menus.menu.append(new MenuItem({ label: window.siyuan.languages.userGuide, icon: "iconHelp", + disabled: window.siyuan.config.readonly, click: () => { mountHelp(); } diff --git a/app/src/mobile/index.ts b/app/src/mobile/index.ts index 1124a6777..f04daf707 100644 --- a/app/src/mobile/index.ts +++ b/app/src/mobile/index.ts @@ -37,9 +37,10 @@ class App { if (!window.webkit?.messageHandlers && !window.JSAndroid) { registerServiceWorker(`${Constants.SERVICE_WORKER_PATH}?v=${Constants.SIYUAN_VERSION}`); } + addBaseURL(); addScriptSync(`${Constants.PROTYLE_CDN}/js/lute/lute.min.js?v=${Constants.SIYUAN_VERSION}`, "protyleLuteScript"); addScript(`${Constants.PROTYLE_CDN}/js/protyle-html.js?v=${Constants.SIYUAN_VERSION}`, "protyleWcHtmlScript"); - addBaseURL(); + this.appId = Constants.SIYUAN_APPID; window.siyuan = { zIndex: 10, @@ -89,30 +90,7 @@ class App { fetchPost("/api/system/getConf", {}, async (confResponse) => { window.siyuan.config = confResponse.data.conf; correctHotkey(siyuanApp); - await loadPlugins(this); - getLocalStorage(() => { - fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages: IObject) => { - window.siyuan.languages = lauguages; - window.siyuan.menus = new Menus(this); - document.title = window.siyuan.languages.siyuanNote; - bootSync(); - loadAssets(confResponse.data.conf.appearance); - initMessage(); - initAssets(); - fetchPost("/api/setting/getCloudUser", {}, userResponse => { - window.siyuan.user = userResponse.data; - fetchPost("/api/system/getEmojiConf", {}, emojiResponse => { - window.siyuan.emojis = emojiResponse.data as IEmoji[]; - setNoteBook(() => { - initFramework(this, confResponse.data.start); - initRightMenu(this); - openChangelog(); - }); - }); - }); - addGA(); - }); - }); + document.addEventListener("touchstart", handleTouchStart, false); document.addEventListener("touchmove", handleTouchMove, false); document.addEventListener("touchend", (event) => { @@ -140,6 +118,51 @@ class App { } } }); + + const promises = [ + loadPlugins(this), + new Promise(resolve => getLocalStorage(resolve)), + new Promise(resolve => fetchGet( + `/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, + (lauguages: IObject) => { + window.siyuan.languages = lauguages; + resolve(); + }, + )), + new Promise(resolve => { + fetchPost("/api/setting/getEmojiConf", {}, emojiResponse => { + window.siyuan.emojis = emojiResponse.data as IEmoji[]; + resolve(); + }); + }), + ]; + + if (!window.siyuan.config.readonly) { + promises.push(new Promise(resolve => { + fetchPost("/api/setting/getCloudUser", {}, userResponse => { + window.siyuan.user = userResponse.data; + resolve(); + }); + })); + } + + await Promise.all(promises); + + if (!window.siyuan.config.readonly) { + bootSync(); + } + + window.siyuan.menus = new Menus(this); + document.title = window.siyuan.languages.siyuanNote; + loadAssets(confResponse.data.conf.appearance); + initMessage(); + initAssets(); + setNoteBook(() => { + initFramework(this, confResponse.data.start); + initRightMenu(this); + openChangelog(); + }); + addGA(); }); } } diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts index e1eb16518..464f45e47 100644 --- a/app/src/protyle/gutter/index.ts +++ b/app/src/protyle/gutter/index.ts @@ -1667,6 +1667,7 @@ export class Gutter { window.siyuan.menus.menu.append(new MenuItem({ label: window.siyuan.languages.wechatReminder, icon: "iconMp", + disabled: window.siyuan.config.readonly, click() { openWechatNotify(nodeElement); } @@ -1678,6 +1679,7 @@ export class Gutter { accelerator: window.siyuan.config.keymap.editor.general.quickMakeCard.custom, iconHTML: '', icon: "iconRiffCard", + disabled: window.siyuan.config.readonly, click() { quickMakeCard(protyle, [nodeElement]); } diff --git a/app/src/protyle/header/openTitleMenu.ts b/app/src/protyle/header/openTitleMenu.ts index 0af807957..dd338bc08 100644 --- a/app/src/protyle/header/openTitleMenu.ts +++ b/app/src/protyle/header/openTitleMenu.ts @@ -112,6 +112,7 @@ export const openTitleMenu = (protyle: IProtyle, position: IPosition) => { window.siyuan.menus.menu.append(new MenuItem({ label: window.siyuan.languages.wechatReminder, icon: "iconMp", + disabled: window.siyuan.config.readonly, click() { openFileWechatNotify(protyle); } @@ -120,6 +121,7 @@ export const openTitleMenu = (protyle: IProtyle, position: IPosition) => { iconHTML: "", label: window.siyuan.languages.spaceRepetition, accelerator: window.siyuan.config.keymap.editor.general.spaceRepetition.custom, + disabled: window.siyuan.config.readonly, click: () => { fetchPost("/api/riff/getTreeRiffDueCards", {rootID: protyle.block.rootID}, (response) => { openCardByData(protyle.app, response.data, "doc", protyle.block.rootID, response.data.name); @@ -128,6 +130,7 @@ export const openTitleMenu = (protyle: IProtyle, position: IPosition) => { }, { iconHTML: "", label: window.siyuan.languages.manage, + disabled: window.siyuan.config.readonly, click: () => { fetchPost("/api/filetree/getHPathByID", { id: protyle.block.rootID @@ -139,6 +142,7 @@ export const openTitleMenu = (protyle: IProtyle, position: IPosition) => { iconHTML: "", label: window.siyuan.languages.quickMakeCard, accelerator: window.siyuan.config.keymap.editor.general.quickMakeCard.custom, + disabled: window.siyuan.config.readonly, click: () => { let titleElement = protyle.title?.element; if (!titleElement) { @@ -153,6 +157,7 @@ export const openTitleMenu = (protyle: IProtyle, position: IPosition) => { riffCardMenu.push({ iconHTML: "", label: window.siyuan.languages.addToDeck, + disabled: window.siyuan.config.readonly, click: () => { makeCard(protyle.app, [protyle.block.rootID]); } @@ -163,6 +168,7 @@ export const openTitleMenu = (protyle: IProtyle, position: IPosition) => { type: "submenu", icon: "iconRiffCard", submenu: riffCardMenu, + disabled: window.siyuan.config.readonly, }).element); window.siyuan.menus.menu.append(new MenuItem({ diff --git a/app/src/protyle/scroll/saveScroll.ts b/app/src/protyle/scroll/saveScroll.ts index 48dc2803a..0ae19c117 100644 --- a/app/src/protyle/scroll/saveScroll.ts +++ b/app/src/protyle/scroll/saveScroll.ts @@ -45,7 +45,7 @@ export const saveScroll = (protyle: IProtyle, getObject = false) => { export const getDocByScroll = (options: { protyle: IProtyle, - scrollAttr: IScrollAttr, + scrollAttr?: IScrollAttr, mergedOptions?: IOptions, cb?: () => void focus?: boolean, @@ -61,7 +61,7 @@ export const getDocByScroll = (options: { actions = [Constants.CB_GET_UNUNDO]; } } - if (options.scrollAttr.zoomInId) { + if (options.scrollAttr?.zoomInId) { fetchPost("/api/filetree/getDoc", { id: options.scrollAttr.zoomInId, size: Constants.SIZE_GET_MAX, @@ -100,9 +100,9 @@ export const getDocByScroll = (options: { return; } fetchPost("/api/filetree/getDoc", { - id: options.scrollAttr.rootId || options.mergedOptions?.blockId || options.protyle.block?.rootID || options.scrollAttr.startId, - startID: options.scrollAttr.startId, - endID: options.scrollAttr.endId, + id: options.scrollAttr?.rootId || options.mergedOptions?.blockId || options.protyle.block?.rootID || options.scrollAttr?.startId, + startID: options.scrollAttr?.startId, + endID: options.scrollAttr?.endId, query: options.protyle.query?.key, queryMethod: options.protyle.query?.method, queryTypes: options.protyle.query?.types, diff --git a/app/src/util/assets.ts b/app/src/util/assets.ts index d2ffad694..314871829 100644 --- a/app/src/util/assets.ts +++ b/app/src/util/assets.ts @@ -150,8 +150,10 @@ export const initAssets = () => { return; } } - window.siyuan.config.appearance = response.data.appearance; - loadAssets(response.data.appearance); + if (response.code === 0) { + window.siyuan.config.appearance = response.data.appearance; + loadAssets(response.data.appearance); + } }); }); }; diff --git a/app/src/window/index.ts b/app/src/window/index.ts index 24a51a7bc..4dc48d3a1 100644 --- a/app/src/window/index.ts +++ b/app/src/window/index.ts @@ -27,9 +27,10 @@ class App { public appId: string; constructor() { + addBaseURL(); addScriptSync(`${Constants.PROTYLE_CDN}/js/lute/lute.min.js?v=${Constants.SIYUAN_VERSION}`, "protyleLuteScript"); addScript(`${Constants.PROTYLE_CDN}/js/protyle-html.js?v=${Constants.SIYUAN_VERSION}`, "protyleWcHtmlScript"); - addBaseURL(); + this.appId = Constants.SIYUAN_APPID; window.siyuan = { zIndex: 10, @@ -146,19 +147,34 @@ class App { }; fetchPost("/api/system/getConf", {}, async (response) => { window.siyuan.config = response.data.conf; - await loadPlugins(this); - getLocalStorage(() => { - fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages: IObject) => { - window.siyuan.languages = lauguages; - window.siyuan.menus = new Menus(this); + + const promises = [ + loadPlugins(this), + new Promise(resolve => getLocalStorage(resolve)), + new Promise(resolve => fetchGet( + `/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, + (lauguages: IObject) => { + window.siyuan.languages = lauguages; + resolve(); + }, + )), + ]; + + if (!window.siyuan.config.readonly) { + promises.push(new Promise(resolve => { fetchPost("/api/setting/getCloudUser", {}, userResponse => { window.siyuan.user = userResponse.data; - init(this); - setTitle(window.siyuan.languages.siyuanNote); - initMessage(); + resolve(); }); - }); - }); + })); + } + + await Promise.all(promises); + + window.siyuan.menus = new Menus(this); + init(this); + setTitle(window.siyuan.languages.siyuanNote); + initMessage(); }); setNoteBook(); initBlockPopover(this); diff --git a/kernel/api/router.go b/kernel/api/router.go index 5d9b53f28..b200f01b0 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -47,7 +47,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/system/setDownloadInstallPkg", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setDownloadInstallPkg) ginServer.Handle("POST", "/api/system/setNetworkProxy", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setNetworkProxy) ginServer.Handle("POST", "/api/system/setWorkspaceDir", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setWorkspaceDir) - ginServer.Handle("POST", "/api/system/getWorkspaces", model.CheckAuth, model.CheckAdminRole, getWorkspaces) + ginServer.Handle("POST", "/api/system/getWorkspaces", model.CheckAuth, getWorkspaces) ginServer.Handle("POST", "/api/system/getMobileWorkspaces", model.CheckAuth, model.CheckAdminRole, getMobileWorkspaces) ginServer.Handle("POST", "/api/system/checkWorkspaceDir", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, checkWorkspaceDir) ginServer.Handle("POST", "/api/system/createWorkspaceDir", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, createWorkspaceDir) @@ -238,7 +238,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/sync/listCloudSyncDir", model.CheckAuth, model.CheckAdminRole, listCloudSyncDir) ginServer.Handle("POST", "/api/sync/performSync", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, performSync) ginServer.Handle("POST", "/api/sync/performBootSync", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, performBootSync) - ginServer.Handle("POST", "/api/sync/getBootSync", model.CheckAuth, getBootSync) + ginServer.Handle("POST", "/api/sync/getBootSync", model.CheckAuth, model.CheckAdminRole, getBootSync) ginServer.Handle("POST", "/api/sync/getSyncInfo", model.CheckAuth, model.CheckAdminRole, getSyncInfo) ginServer.Handle("POST", "/api/sync/exportSyncProviderS3", model.CheckAuth, model.CheckAdminRole, exportSyncProviderS3) ginServer.Handle("POST", "/api/sync/importSyncProviderS3", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importSyncProviderS3) @@ -318,7 +318,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/setting/setSearch", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setSearch) ginServer.Handle("POST", "/api/setting/setKeymap", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setKeymap) ginServer.Handle("POST", "/api/setting/setAppearance", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setAppearance) - ginServer.Handle("POST", "/api/setting/getCloudUser", model.CheckAuth, getCloudUser) + ginServer.Handle("POST", "/api/setting/getCloudUser", model.CheckAuth, model.CheckAdminRole, getCloudUser) ginServer.Handle("POST", "/api/setting/logoutCloudUser", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, logoutCloudUser) ginServer.Handle("POST", "/api/setting/login2faCloudUser", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, login2faCloudUser) ginServer.Handle("POST", "/api/setting/setEmoji", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setEmoji) diff --git a/kernel/api/setting.go b/kernel/api/setting.go index 901035007..4a6322455 100644 --- a/kernel/api/setting.go +++ b/kernel/api/setting.go @@ -590,10 +590,6 @@ func getCloudUser(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) - if !model.IsAdminRoleContext(c) { - return - } - arg, ok := util.JsonArg(c, ret) if !ok { return diff --git a/kernel/api/sync.go b/kernel/api/sync.go index 6f122846c..f793cbf08 100644 --- a/kernel/api/sync.go +++ b/kernel/api/sync.go @@ -18,13 +18,14 @@ package api import ( "encoding/hex" - "github.com/siyuan-note/logging" "io" "net/http" "os" "path/filepath" "time" + "github.com/siyuan-note/logging" + "github.com/88250/gulu" "github.com/gin-gonic/gin" "github.com/siyuan-note/siyuan/kernel/conf" @@ -381,10 +382,6 @@ func getBootSync(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) - if !model.IsAdminRoleContext(c) { - return - } - if model.Conf.Sync.Enabled && 1 == model.BootSyncSucc { ret.Code = 1 ret.Msg = model.Conf.Language(17) diff --git a/kernel/api/workspace.go b/kernel/api/workspace.go index 16975c1f9..c126c3c33 100644 --- a/kernel/api/workspace.go +++ b/kernel/api/workspace.go @@ -235,6 +235,13 @@ func getWorkspaces(c *gin.Context) { return } + if role := model.GetGinContextRole(c); !model.IsValidRole(role, []model.Role{ + model.RoleAdministrator, + }) { + ret.Data = []*Workspace{} + return + } + var workspaces, openedWorkspaces, closedWorkspaces []*Workspace for _, p := range workspacePaths { closed := !util.IsWorkspaceLocked(p) diff --git a/kernel/model/role.go b/kernel/model/role.go index 79f6b0f18..5f0fca3aa 100644 --- a/kernel/model/role.go +++ b/kernel/model/role.go @@ -54,7 +54,3 @@ func GetGinContextRole(c *gin.Context) Role { return RoleVisitor } } - -func IsAdminRoleContext(c *gin.Context) bool { - return GetGinContextRole(c) == RoleAdministrator -}