✨ Support read-only publish service
* 🎨 kernel supports read-only publishing services * 🐛 Fix authentication vulnerabilities * 🎨 Protect secret information * 🎨 Adjust the permission control * 🎨 Adjust the permission control * 🎨 Fixed the vulnerability that `getFile` gets file `conf.json` * 🎨 Add API `/api/setting/setPublish` * 🎨 Add API `/api/setting/getPublish` * 🐛 Fixed the issue that PWA-related files could not pass BasicAuth * 🎨 Add a settings panel for publishing features * 📝 Add guide for `Publish Service` * 📝 Update Japanese user guide * 🎨 Merge fixed static file services
This commit is contained in:
parent
536879cb84
commit
ba2193403d
47 changed files with 3690 additions and 375 deletions
|
@ -1,4 +1,17 @@
|
|||
{
|
||||
"publish": "Publish",
|
||||
"publishService": "Publish service",
|
||||
"publishServiceNotStarted": "Publish Service Not Started",
|
||||
"publishServiceTip": "When enabled, the publish service will be started. This service publishes the content of the current workspace in read-only mode on the local network.",
|
||||
"publishServicePort": "Service port",
|
||||
"publishServicePortTip": "Enable the publish service using the specified port number. If set to <code class='fn__code'>0</code>, a random port will be used.",
|
||||
"publishServiceAddresses": "Service access addresses",
|
||||
"publishServiceAddressesTip": "Possible network addresses to access the publish service.",
|
||||
"publishServiceAuth": "Service basic authentication",
|
||||
"publishServiceAuthTip": "When enabled, authentication is required to access the publish service.",
|
||||
"publishServiceAuthAccounts": "Authenticated accounts",
|
||||
"publishServiceAuthAccountsTip": "List of Basic authentication accounts. Visitors need to enter the username and password from this list to view the published content.",
|
||||
"publishServiceAuthAccountAdd": "Add account",
|
||||
"copyMirror": "Copy mirror",
|
||||
"duplicateMirror": "Duplicate mirror",
|
||||
"duplicateCompletely": "Duplicate completely",
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
{
|
||||
"publish": "Publicar",
|
||||
"publishService": "Publicar servicio",
|
||||
"publishServiceNotStarted": "Servicio de publicación no iniciado",
|
||||
"publishServiceTip": "Al activar esto, se iniciará el servicio de publicación. Este servicio publicará el contenido del espacio de trabajo actual en modo de solo lectura en la LAN",
|
||||
"publishServicePort": "Número de puerto del servicio",
|
||||
"publishServicePortTip": "Activar el servicio de publicación con el número de puerto especificado. Si se establece en 0, se utilizará un puerto aleatorio",
|
||||
"publishServiceAddresses": "Direcciones de acceso al servicio",
|
||||
"publishServiceAddressesTip": "Direcciones de red desde las que se puede acceder al servicio de publicación",
|
||||
"publishServiceAuth": "Autenticación básica del servicio",
|
||||
"publishServiceAuthTip": "Al activar esto, se requerirá autenticación al acceder al servicio de publicación",
|
||||
"publishServiceAuthAccounts": "Cuentas de autenticación",
|
||||
"publishServiceAuthAccountsTip": "Lista de cuentas de autenticación básica. Después de activar la autenticación básica, los visitantes deberán ingresar el nombre de usuario y la contraseña de la lista para ver el contenido publicado",
|
||||
"publishServiceAuthAccountAdd": "Agregar cuenta",
|
||||
"copyMirror": "Copiar espejo",
|
||||
"duplicateMirror": "Espejo duplicado",
|
||||
"duplicateCompletely": "Duplicar completamente",
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
{
|
||||
"publish": "Publier",
|
||||
"publishService": "Publier le service",
|
||||
"publishServiceNotStarted": "Service de publication non démarré",
|
||||
"publishServiceTip": "Lorsqu'activé, le service de publication démarre. Ce service publie en mode lecture seule le contenu de l'espace de travail actuel dans le réseau local.",
|
||||
"publishServicePort": "Numéro de port du service",
|
||||
"publishServicePortTip": "Active le service de publication avec le numéro de port spécifié. Si défini sur 0, un port aléatoire sera utilisé.",
|
||||
"publishServiceAddresses": "Adresses d'accès au service",
|
||||
"publishServiceAddressesTip": "Adresses réseau qui peuvent accéder au service de publication",
|
||||
"publishServiceAuth": "Authentification Basic du service",
|
||||
"publishServiceAuthTip": "Lorsqu'activé, une authentification est requise pour accéder au service de publication",
|
||||
"publishServiceAuthAccounts": "Comptes d'authentification",
|
||||
"publishServiceAuthAccountsTip": "Liste des comptes d'authentification Basic. Lorsque l'authentification Basic est activée, les visiteurs doivent entrer un nom d'utilisateur et un mot de passe figurant dans cette liste pour consulter le contenu publié.",
|
||||
"publishServiceAuthAccountAdd": "Ajouter un compte",
|
||||
"copyMirror": "Copier le miroir",
|
||||
"duplicateMirror": "Miroir en double",
|
||||
"duplicateCompletely": "Dupliquer complètement",
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
{
|
||||
"publish": "公開する",
|
||||
"publishService": "サービスを公開する",
|
||||
"publishServiceNotStarted": "サービスが開始されていません",
|
||||
"publishServiceTip": "有効にすると、サービスを開始します。このサービスは、現在のワークスペースの内容を読み取り専用モードでローカルネットワークに公開します",
|
||||
"publishServicePort": "サービスポート",
|
||||
"publishServicePortTip": "指定したポート番号を使用してサービスを有効にします。0に設定するとランダムなポートが使用されます",
|
||||
"publishServiceAddresses": "サービスアドレス",
|
||||
"publishServiceAddressesTip": "サービスを公開することが可能なネットワークアドレス",
|
||||
"publishServiceAuth": "サービスの基本認証",
|
||||
"publishServiceAuthTip": "有効にすると、公開サービスへのアクセス時に認証が必要になります",
|
||||
"publishServiceAuthAccounts": "認証アカウント",
|
||||
"publishServiceAuthAccountsTip": "基本認証アカウントのリスト。基本認証を有効にした場合、訪問者はリスト内のユーザー名とパスワードを入力して公開内容を表示することができます",
|
||||
"publishServiceAuthAccountAdd": "アカウントを追加する",
|
||||
"copyMirror": "ミラーをコピー",
|
||||
"duplicateMirror": "ミラーを複製",
|
||||
"duplicateCompletely": "完全に複製",
|
||||
|
@ -1523,4 +1536,4 @@
|
|||
"247": "ファイル [%s] は制限サイズ [%s] を超えているためアップロードされませんでした",
|
||||
"248": "目標の見出しがコンテナブロック内にあるためドロップできません"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
{
|
||||
"publish": "發布",
|
||||
"publishService": "發布服務",
|
||||
"publishServiceNotStarted": "發布服務未啟動",
|
||||
"publishServiceTip": "啟用後將啟動發布服務。該服務以只讀模式在區域網中發布當前工作空間的內容",
|
||||
"publishServicePort": "服務端口號",
|
||||
"publishServicePortTip": "使用指定的端口號啟用發布服務。若設置為 <code class='fn__code'>0</code> 則使用隨機端口",
|
||||
"publishServiceAddresses": "服務訪問地址",
|
||||
"publishServiceAddressesTip": "可能訪問到發布服務的網路地址",
|
||||
"publishServiceAuth": "服務 Basic 認證",
|
||||
"publishServiceAuthTip": "啟用後在訪問發布服務時需要進行認證",
|
||||
"publishServiceAuthAccounts": "認證帳戶",
|
||||
"publishServiceAuthAccountsTip": "Basic 認證帳戶列表。啟用 Basic 認證後訪問者輸入列表中的用戶名與密碼後才能查看發布的內容",
|
||||
"publishServiceAuthAccountAdd": "添加帳戶",
|
||||
"copyMirror": "複製鏡像",
|
||||
"duplicateMirror": "複製為鏡像副本",
|
||||
"duplicateCompletely": "複製為完整副本",
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
{
|
||||
"publish": "发布",
|
||||
"publishService": "发布服务",
|
||||
"publishServiceNotStarted": "发布服务未启动",
|
||||
"publishServiceTip": "启用后将启动发布服务。该服务以只读模式在局域网中发布当前工作空间的内容",
|
||||
"publishServicePort": "服务端口号",
|
||||
"publishServicePortTip": "使用指定的端口号启用发布服务。若设置为 <code class='fn__code'>0</code> 则使用随机端口",
|
||||
"publishServiceAddresses": "服务访问地址",
|
||||
"publishServiceAddressesTip": "可能访问到发布服务的网络地址",
|
||||
"publishServiceAuth": "服务 Basic 认证",
|
||||
"publishServiceAuthTip": "启用后访问者在访问发布服务时需要使用用户名与密码进行认证",
|
||||
"publishServiceAuthAccounts": "认证账户",
|
||||
"publishServiceAuthAccountsTip": "Basic 认证账户列表。访问者输入列表中的用户名与密码后才能查看发布的内容",
|
||||
"publishServiceAuthAccountAdd": "添加账户",
|
||||
"copyMirror": "复制镜像",
|
||||
"duplicateMirror": "复制为镜像副本",
|
||||
"duplicateCompletely": "复制为完整副本",
|
||||
|
|
2
app/guide/20210808180117-6v0mkxr/.gitignore
vendored
2
app/guide/20210808180117-6v0mkxr/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
.idea/
|
||||
.siyuan/history/
|
|
@ -1 +1 @@
|
|||
{"20200923234011-ieuun1p":1,"20200923234602-gy54e67":8,"20200923234731-h3zkwm2":3,"20200924093441-ft2rhps":1,"20200924095938-a9p5450":2,"20200924100110-vcg96wy":1,"20200924100635-ms0p9lb":6,"20200924100717-yzwzn64":21,"20200924100744-br924ar":10,"20200924100808-j9sddk9":2,"20200924100906-0u4zfq3":4,"20200924100950-9op5xi1":18,"20200924101106-19z4kaa":1,"20200924101200-gss5vee":4,"20200924101225-k254i8g":2,"20200924101256-f8b1sbi":3,"20201004194026-s8h2cog":19,"20201117112518-dott91x":6,"20201121224345-rc27qvo":9,"20201204184532-3qm9l8n":11,"20201210233038-3xr19g5":5,"20201222100222-q47d64s":3,"20201222100339-i5hzcph":2,"20201227201128-m1wrouw":20,"20201227201751-gv0fpx2":22,"20210110181011-fbhoesf":5,"20210117215840-jcl17fx":4,"20210127203829-qe2mzof":12,"20210331201142-4g923es":14,"20210505164949-c085p1d":3,"20210613191509-cbkxcbz":7,"20210615213222-vs5tzbd":15,"20210721112159-9p645xm":1,"20210721112206-mhr9wxi":2,"20210721160238-yvhbh0h":4,"20210808180303-6yi0dv5":1,"20210808180303-axh6q1d":4,"20210808180303-h361q1i":2,"20210808180303-l3qg72k":3,"20210808180303-xaduj2o":5,"20210824202056-udkf7wg":8,"20211010212318-3wx2kqb":13,"20220105101227-n5zpr1a":6,"20220415232231-pqcizol":1,"20220628204454-hhxohv5":2,"20220708103401-mgydrfg":3,"20221016204105-qx2aq0g":3,"20221223221636-ms2b4w9":16,"20230104152135-1iei0xa":23,"20230106104821-9nfphwm":1,"20230304000547-ibldj1z":17,"20230405172236-pg3l9eu":6,"20230429115711-ejbts4s":5,"20230506205948-yah52eb":9,"20230802114825-2jkkct7":5,"20230805231614-vqn28eh":7,"20230805231816-h1z9mpc":2,"20230805232018-hgrq0ju":1,"20230805232134-3d6mx2k":2,"20240113110040-7sgw8kl":2,"20240119211017-1vbbt95":4,"20240119212048-0huuevw":5,"20240208172514-9dsv6na":7,"20240317202444-5txwumu":7}
|
||||
{"20200923234011-ieuun1p":1,"20200923234602-gy54e67":8,"20200923234731-h3zkwm2":3,"20200924093441-ft2rhps":1,"20200924095938-a9p5450":2,"20200924100110-vcg96wy":1,"20200924100635-ms0p9lb":6,"20200924100717-yzwzn64":21,"20200924100744-br924ar":10,"20200924100808-j9sddk9":2,"20200924100906-0u4zfq3":4,"20200924100950-9op5xi1":18,"20200924101106-19z4kaa":1,"20200924101200-gss5vee":4,"20200924101225-k254i8g":2,"20200924101256-f8b1sbi":3,"20201004194026-s8h2cog":19,"20201117112518-dott91x":6,"20201121224345-rc27qvo":9,"20201204184532-3qm9l8n":11,"20201210233038-3xr19g5":5,"20201222100222-q47d64s":3,"20201222100339-i5hzcph":2,"20201227201128-m1wrouw":20,"20201227201751-gv0fpx2":22,"20210110181011-fbhoesf":5,"20210117215840-jcl17fx":4,"20210127203829-qe2mzof":12,"20210331201142-4g923es":14,"20210505164949-c085p1d":3,"20210613191509-cbkxcbz":7,"20210615213222-vs5tzbd":15,"20210721112159-9p645xm":1,"20210721112206-mhr9wxi":2,"20210721160238-yvhbh0h":4,"20210808180303-6yi0dv5":1,"20210808180303-axh6q1d":4,"20210808180303-h361q1i":2,"20210808180303-l3qg72k":3,"20210808180303-xaduj2o":5,"20210824202056-udkf7wg":8,"20211010212318-3wx2kqb":13,"20220105101227-n5zpr1a":6,"20220415232231-pqcizol":1,"20220628204454-hhxohv5":2,"20220708103401-mgydrfg":3,"20221016204105-qx2aq0g":3,"20221223221636-ms2b4w9":16,"20230104152135-1iei0xa":23,"20230106104821-9nfphwm":1,"20230304000547-ibldj1z":17,"20230405172236-pg3l9eu":6,"20230429115711-ejbts4s":5,"20230506205948-yah52eb":9,"20230802114825-2jkkct7":5,"20230805231614-vqn28eh":7,"20230805231816-h1z9mpc":2,"20230805232018-hgrq0ju":1,"20230805232134-3d6mx2k":2,"20240113110040-7sgw8kl":2,"20240119211017-1vbbt95":4,"20240119212048-0huuevw":5,"20240208172514-9dsv6na":7,"20240317202444-5txwumu":7,"20240517031132-jmr5ihm":24}
|
|
@ -0,0 +1,526 @@
|
|||
{
|
||||
"ID": "20240517031132-jmr5ihm",
|
||||
"Spec": "1",
|
||||
"Type": "NodeDocument",
|
||||
"Properties": {
|
||||
"id": "20240517031132-jmr5ihm",
|
||||
"title": "Publish service",
|
||||
"type": "doc",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-um049u9",
|
||||
"Type": "NodeHeading",
|
||||
"HeadingLevel": 2,
|
||||
"Properties": {
|
||||
"id": "20240517031304-um049u9",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "Overview"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-kebcgzv",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031304-kebcgzv",
|
||||
"updated": "20240517031305"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "Joplin supports publishing the content of the current workspace in read-only mode on the local area network."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-7e0kvj3",
|
||||
"Type": "NodeHeading",
|
||||
"HeadingLevel": 2,
|
||||
"Properties": {
|
||||
"id": "20240517031304-7e0kvj3",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "Usage"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-gt5qj60",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031304-gt5qj60",
|
||||
"updated": "20240517031305"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-sjppgk3",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031304-sjppgk3",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-r9a0anm",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031304-r9a0anm",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "Open "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "Settings"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " - "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "Publish"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " to enter the publishing service settings panel."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-u6inl9h",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031304-u6inl9h",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-ye7ittw",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031304-ye7ittw",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "Set the "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "Server port"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-olvdqhj",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031304-olvdqhj",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-1ttdtl4",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031304-1ttdtl4",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-sl59b81",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031304-sl59b81",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "The default port number is "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "code",
|
||||
"TextMarkTextContent": "6808"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-t37dfgj",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031304-t37dfgj",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-mxx5df4",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031304-mxx5df4",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "If the port number is set to "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "code",
|
||||
"TextMarkTextContent": "0"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ", a random port will be used."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-y4kcmaf",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031304-y4kcmaf",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-5qilsih",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031304-5qilsih",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "If access control is required for the publishing service:"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-659m8fi",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031304-659m8fi",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-xh0kq2y",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031304-xh0kq2y",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-lay209u",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031304-lay209u",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "Add "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "Authenticated accounts"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " and enable the "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "Service basic authentication"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " switch."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-ri1nm5j",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031304-ri1nm5j",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-4y267ml",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031304-4y267ml",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "When enabled, the publishing service will use the "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "a",
|
||||
"TextMarkAHref": "https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme",
|
||||
"TextMarkTextContent": "Basic authentication scheme"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " to authenticate visitors."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-h61xxm7",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031304-h61xxm7",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-1k96w0z",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031304-1k96w0z",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-l5hafpz",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031304-l5hafpz",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "Visitors must enter the username and password set in the \"Authentication Accounts\" before browsing the published content."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-0nps2p8",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031304-0nps2p8",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-y16fc8r",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031304-y16fc8r",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "Enable the "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "Publish service"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " switch."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-6cy4lbq",
|
||||
"Type": "NodeHeading",
|
||||
"HeadingLevel": 2,
|
||||
"Properties": {
|
||||
"id": "20240517031304-6cy4lbq",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "Note"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-3slh48m",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031304-3slh48m",
|
||||
"updated": "20240517031305"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-uquw6i6",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031304-uquw6i6",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-j38u7hu",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031304-j38u7hu",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "After enabling the publishing service, visitors can browse the content of the entire workspace."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031304-c6iqquc",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031304-c6iqquc",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031304-1qsa7qz",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031304-1qsa7qz",
|
||||
"updated": "20240517031304"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "When "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "Service basic authentication"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " is disabled, all visitors can browse the content of the entire workspace without authentication."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
2
app/guide/20210808180117-czj9bvb/.gitignore
vendored
2
app/guide/20210808180117-czj9bvb/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
.idea/
|
||||
.siyuan/history/
|
|
@ -1 +1 @@
|
|||
{"20200812220555-lj3enxa":1,"20200813004551-gm0pbn1":18,"20200813004931-q4cu8na":1,"20200813013559-sgbzl5k":3,"20200813093015-u6bopdt":3,"20200813125307-pxsjela":2,"20200813131152-0wk5akh":4,"20200813163359-v04n73b":10,"20200822191536-rm6hwid":4,"20200825162036-4dx365o":1,"20200828105441-r76vmu5":21,"20200905090211-2vixtlf":2,"20200910201551-h4twhas":6,"20200915214115-42b8zma":10,"20200922102318-oz84yu3":2,"20201004184819-nj8ibyg":19,"20201117101902-2ewjjum":6,"20201121212605-9td1a62":11,"20201204181006-7bkppue":11,"20201210103036-1x3vm8t":5,"20201222093044-rx4zjoy":2,"20201222095049-hghafhe":3,"20201227173504-847cs1q":20,"20201227194925-7ipoiv6":22,"20210110175347-2xrwoiq":5,"20210117211155-56n4odu":4,"20210127202655-2334vvv":12,"20210331200042-94gs1hh":14,"20210505163537-oo97zov":3,"20210612224500-ywcms1m":7,"20210615211733-v6rzowm":15,"20210808180320-abz7w6k":2,"20210808180320-fqgskfj":1,"20210808180320-gyngv2x":3,"20210808180320-qgr0b3q":5,"20210808180321-hbvl5c2":6,"20210824201257-cy7icrc":8,"20211010211311-ffz0wbu":13,"20220415190432-r3xqn3r":1,"20220628204444-9n0y9h2":2,"20221016213308-uz5af79":3,"20221223215557-o6gfsoy":16,"20230104144904-39br4c6":23,"20230106101434-e6g4av3":1,"20230303235619-ex5l63e":17,"20230405155631-leo4vc6":6,"20230428153709-hioyy5l":7,"20230429114837-70asb4j":5,"20230506210010-houyyvy":9,"20230519105228-hm0y74i":8,"20230805222417-2lj3dvk":7,"20230805225107-qm1m2f5":2,"20230805230131-sn7obzb":1,"20230805230218-aea8icj":2,"20230808120347-3cob0nb":2,"20230808120347-mw3qrwy":4,"20230808120347-pzvmkik":1,"20230808120348-hynr7og":5,"20230808120348-lgcp9zm":3,"20230808120348-vaxi6eq":6,"20230808120348-yut741f":7,"20240113102857-c63dmo5":2,"20240119205452-o8xp4ve":4,"20240119205543-hknwwrl":5,"20240208113259-nykkvaq":7,"20240317200013-fim8wm8":9}
|
||||
{"20200812220555-lj3enxa":1,"20200813004551-gm0pbn1":18,"20200813004931-q4cu8na":1,"20200813013559-sgbzl5k":3,"20200813093015-u6bopdt":3,"20200813125307-pxsjela":2,"20200813131152-0wk5akh":4,"20200813163359-v04n73b":10,"20200822191536-rm6hwid":4,"20200825162036-4dx365o":1,"20200828105441-r76vmu5":21,"20200905090211-2vixtlf":2,"20200910201551-h4twhas":6,"20200915214115-42b8zma":10,"20200922102318-oz84yu3":2,"20201004184819-nj8ibyg":19,"20201117101902-2ewjjum":6,"20201121212605-9td1a62":11,"20201204181006-7bkppue":11,"20201210103036-1x3vm8t":5,"20201222093044-rx4zjoy":2,"20201222095049-hghafhe":3,"20201227173504-847cs1q":20,"20201227194925-7ipoiv6":22,"20210110175347-2xrwoiq":5,"20210117211155-56n4odu":4,"20210127202655-2334vvv":12,"20210331200042-94gs1hh":14,"20210505163537-oo97zov":3,"20210612224500-ywcms1m":7,"20210615211733-v6rzowm":15,"20210808180320-abz7w6k":2,"20210808180320-fqgskfj":1,"20210808180320-gyngv2x":3,"20210808180320-qgr0b3q":5,"20210808180321-hbvl5c2":6,"20210824201257-cy7icrc":8,"20211010211311-ffz0wbu":13,"20220415190432-r3xqn3r":1,"20220628204444-9n0y9h2":2,"20221016213308-uz5af79":3,"20221223215557-o6gfsoy":16,"20230104144904-39br4c6":23,"20230106101434-e6g4av3":1,"20230303235619-ex5l63e":17,"20230405155631-leo4vc6":6,"20230428153709-hioyy5l":7,"20230429114837-70asb4j":5,"20230506210010-houyyvy":9,"20230519105228-hm0y74i":8,"20230805222417-2lj3dvk":7,"20230805225107-qm1m2f5":2,"20230805230131-sn7obzb":1,"20230805230218-aea8icj":2,"20230808120347-3cob0nb":2,"20230808120347-mw3qrwy":4,"20230808120347-pzvmkik":1,"20230808120348-hynr7og":5,"20230808120348-lgcp9zm":3,"20230808120348-vaxi6eq":6,"20230808120348-yut741f":7,"20240113102857-c63dmo5":2,"20240119205452-o8xp4ve":4,"20240119205543-hknwwrl":5,"20240208113259-nykkvaq":7,"20240317200013-fim8wm8":9,"20240517031028-xqinazo":24}
|
|
@ -0,0 +1,540 @@
|
|||
{
|
||||
"ID": "20240517031028-xqinazo",
|
||||
"Spec": "1",
|
||||
"Type": "NodeDocument",
|
||||
"Properties": {
|
||||
"id": "20240517031028-xqinazo",
|
||||
"title": "发布服务",
|
||||
"type": "doc",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-7ox0m9z",
|
||||
"Type": "NodeHeading",
|
||||
"HeadingLevel": 2,
|
||||
"Properties": {
|
||||
"id": "20240517031044-7ox0m9z",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "概述"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-6mppc0k",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031044-6mppc0k",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "思源笔记支持以只读模式在局域网中发布当前工作空间的内容。"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-anhkwow",
|
||||
"Type": "NodeHeading",
|
||||
"HeadingLevel": 2,
|
||||
"Properties": {
|
||||
"id": "20240517031044-anhkwow",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "使用方式"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-0vj6or7",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031044-0vj6or7",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-8ugboo7",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031044-8ugboo7",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-grogeue",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031044-grogeue",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "打开 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "设置"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " - "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "发布"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 进入发布服务的设置面板"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-mta08zv",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031044-mta08zv",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-7dg9xy9",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031044-7dg9xy9",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "设置 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "服务端口号"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-vzj8o1a",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031044-vzj8o1a",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-t2igim6",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031044-t2igim6",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-8ghv9tj",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031044-8ghv9tj",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "默认的端口号为 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "code",
|
||||
"TextMarkTextContent": "6808"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-3oto1iz",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031044-3oto1iz",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-0m68jzx",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031044-0m68jzx",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "若端口号设置为 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "code",
|
||||
"TextMarkTextContent": "0"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 将使用随机端口"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-ddii8sb",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031044-ddii8sb",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-vaiskyz",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031044-vaiskyz",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "若需要对发布服务进行访问控制"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-ze7l6sg",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031044-ze7l6sg",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-fxpcxvc",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031044-fxpcxvc",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-bno9bca",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031044-bno9bca",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "添加 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "认证账户"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 并开启 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "服务 Basic 认证"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 开关"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-29kw4ks",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031044-29kw4ks",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-g05n8gc",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031044-g05n8gc",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "开启后发布服务将使用 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "a",
|
||||
"TextMarkAHref": "https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Authentication#basic_验证方案",
|
||||
"TextMarkTextContent": "Basic 验证方案"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 对访问者进行认证"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-e54f9vf",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031044-e54f9vf",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-kr1t232",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031044-kr1t232",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-rf8nyba",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031044-rf8nyba",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "访问者在浏览发布内容前必须正确输入 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "认证账户"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 中设置的用户名与密码"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-s5d5aak",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031044-s5d5aak",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-ec9vaac",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031044-ec9vaac",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "开启 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "发布服务"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 开关"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-6le4t1r",
|
||||
"Type": "NodeHeading",
|
||||
"HeadingLevel": 2,
|
||||
"Properties": {
|
||||
"id": "20240517031044-6le4t1r",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "tag",
|
||||
"TextMarkTextContent": "注意"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-ahzjzvg",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031044-ahzjzvg",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-8f3g2fd",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031044-8f3g2fd",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-uiys91u",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031044-uiys91u",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "开启发布服务后访问者可以浏览整个工作空间的内容"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031044-979coq3",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031044-979coq3",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031044-7be46qj",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031044-7be46qj",
|
||||
"updated": "20240517031044"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "关闭 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "服务 Basic 认证"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 后所有的访问者无需认证即可浏览整个工作空间的内容"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
2
app/guide/20211226090932-5lcq56f/.gitignore
vendored
2
app/guide/20211226090932-5lcq56f/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
.idea/
|
||||
.siyuan/history/
|
|
@ -1 +1 @@
|
|||
{"20211226114339-dk0gtpr":8,"20211226114929-08ap1r0":9,"20211226115043-afhev0g":4,"20211226115227-r1rty9v":3,"20211226115423-d5z1joq":1,"20211226115825-mhcslw2":1,"20211226120055-9mityht":1,"20211226120147-ib6yy3i":2,"20211226120247-63nd8y5":3,"20211226120349-rbkmozu":4,"20211226120422-bkzsd2e":5,"20211226120508-yzh70eh":6,"20211226120802-77aj0is":7,"20211226120854-dr1jfx2":2,"20211226120933-vnjgwwh":3,"20211226121109-f060fkg":4,"20211226121203-rjjngpz":5,"20211226121319-emrk2yy":1,"20211226121322-9argcys":3,"20211226121329-c5v3dto":22,"20211226121332-irgblss":4,"20211226121438-xaafdo8":2,"20211226121503-k3jma6m":1,"20211226121808-fnxmngk":2,"20211226122358-hctqcn5":21,"20211226122459-08mi5cq":20,"20211226122523-rl8356a":19,"20211226122549-jktxego":18,"20211226122707-8cr09co":15,"20211226122728-cnqf7rz":14,"20211226122814-r1rdpcx":13,"20211226122943-st7fpcj":12,"20211226123004-dplpw0o":11,"20211226123038-4umgpxy":10,"20211226123101-qjw03ab":8,"20211226123130-jpeg5b2":6,"20211226123154-fd5e001":5,"20211226123216-tlxw66f":4,"20211226123241-51pujtr":3,"20211226123302-akitvb1":2,"20220105101348-corstqc":6,"20220415232129-shpzg6r":1,"20220628204420-ui79vkt":2,"20220708102441-u6wopo9":3,"20221016213639-1nag9jj":3,"20221223221501-mops33i":16,"20230104151953-48hwkwf":23,"20230106104645-o838uew":1,"20230304000829-9jwu3po":17,"20230405172131-yb16aax":6,"20230429115206-ob8nl8t":5,"20230506211210-1roopyo":9,"20230805232636-zh0adz2":6,"20230805232719-04mqbcx":2,"20230805232903-erdoerp":1,"20230805232920-5fdco36":2,"20240113110500-dz2ae4n":2,"20240119210914-a2tm8c4":4,"20240119212000-qkldbjm":5,"20240208171522-y7dxcno":7,"20240317202230-l8duv3r":7,"20240508010647-8nuyk31":5}
|
||||
{"20211226114339-dk0gtpr":8,"20211226114929-08ap1r0":9,"20211226115043-afhev0g":4,"20211226115227-r1rty9v":3,"20211226115423-d5z1joq":1,"20211226115825-mhcslw2":1,"20211226120055-9mityht":1,"20211226120147-ib6yy3i":2,"20211226120247-63nd8y5":3,"20211226120349-rbkmozu":4,"20211226120422-bkzsd2e":5,"20211226120508-yzh70eh":6,"20211226120802-77aj0is":7,"20211226120854-dr1jfx2":2,"20211226120933-vnjgwwh":3,"20211226121109-f060fkg":4,"20211226121203-rjjngpz":5,"20211226121319-emrk2yy":1,"20211226121322-9argcys":3,"20211226121329-c5v3dto":22,"20211226121332-irgblss":4,"20211226121438-xaafdo8":2,"20211226121503-k3jma6m":1,"20211226121808-fnxmngk":2,"20211226122358-hctqcn5":21,"20211226122459-08mi5cq":20,"20211226122523-rl8356a":19,"20211226122549-jktxego":18,"20211226122707-8cr09co":15,"20211226122728-cnqf7rz":14,"20211226122814-r1rdpcx":13,"20211226122943-st7fpcj":12,"20211226123004-dplpw0o":11,"20211226123038-4umgpxy":10,"20211226123101-qjw03ab":8,"20211226123130-jpeg5b2":6,"20211226123154-fd5e001":5,"20211226123216-tlxw66f":4,"20211226123241-51pujtr":3,"20211226123302-akitvb1":2,"20220105101348-corstqc":6,"20220415232129-shpzg6r":1,"20220628204420-ui79vkt":2,"20220708102441-u6wopo9":3,"20221016213639-1nag9jj":3,"20221223221501-mops33i":16,"20230104151953-48hwkwf":23,"20230106104645-o838uew":1,"20230304000829-9jwu3po":17,"20230405172131-yb16aax":6,"20230429115206-ob8nl8t":5,"20230506211210-1roopyo":9,"20230805232636-zh0adz2":6,"20230805232719-04mqbcx":2,"20230805232903-erdoerp":1,"20230805232920-5fdco36":2,"20240113110500-dz2ae4n":2,"20240119210914-a2tm8c4":4,"20240119212000-qkldbjm":5,"20240208171522-y7dxcno":7,"20240317202230-l8duv3r":7,"20240508010647-8nuyk31":5,"20240517031052-mgoxs16":24}
|
|
@ -0,0 +1,540 @@
|
|||
{
|
||||
"ID": "20240517031052-mgoxs16",
|
||||
"Spec": "1",
|
||||
"Type": "NodeDocument",
|
||||
"Properties": {
|
||||
"id": "20240517031052-mgoxs16",
|
||||
"title": "發布服務",
|
||||
"type": "doc",
|
||||
"updated": "20240517031115"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031115-pjkrctx",
|
||||
"Type": "NodeHeading",
|
||||
"HeadingLevel": 2,
|
||||
"Properties": {
|
||||
"id": "20240517031115-pjkrctx",
|
||||
"updated": "20240517031115"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "概述"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-a0xf075",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031116-a0xf075",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "思源筆記支援以只讀模式在區域網路中發佈當前工作空間的內容。"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-ml8jd6n",
|
||||
"Type": "NodeHeading",
|
||||
"HeadingLevel": 2,
|
||||
"Properties": {
|
||||
"id": "20240517031116-ml8jd6n",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "使用方式"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-5u42tlr",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031116-5u42tlr",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-06mevu7",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031116-06mevu7",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-wqo2aje",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031116-wqo2aje",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "開啟 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "設定"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " - "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "發佈"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 進入發佈服務的設定面板"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-dsvhebl",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031116-dsvhebl",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-13481er",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031116-13481er",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "設定 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "服務端口號"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-sjbg5cn",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031116-sjbg5cn",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-z1q43ui",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031116-z1q43ui",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-ssdjmbf",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031116-ssdjmbf",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "默認的端口號為 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "code",
|
||||
"TextMarkTextContent": "6808"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-jkcxgaj",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031116-jkcxgaj",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-ka1wome",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031116-ka1wome",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "若端口號設定為 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "code",
|
||||
"TextMarkTextContent": "0"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 將使用隨機端口"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-ipkirs4",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031116-ipkirs4",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-g8qr29s",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031116-g8qr29s",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "若需要對發佈服務進行訪問控制"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-maj6mmd",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031116-maj6mmd",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-du7rttx",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031116-du7rttx",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-ct3chrz",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031116-ct3chrz",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "添加 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "認證帳戶"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 並開啟 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "服務 Basic 認證"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 開關"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-dlaep2b",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031116-dlaep2b",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-3u2v8g7",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031116-3u2v8g7",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "開啟後發佈服務將使用 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "a",
|
||||
"TextMarkAHref": "https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Authentication#basic_验证方案",
|
||||
"TextMarkTextContent": "Basic 驗證方案"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 對訪問者進行認證"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-qmzfje7",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031116-qmzfje7",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-xthto7w",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031116-xthto7w",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-kbz5qye",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031116-kbz5qye",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "訪問者在瀏覽發佈內容前必須正確輸入 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "認證帳戶"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 中設定的用戶名與密碼"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-bx01v3n",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031116-bx01v3n",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-44j60lx",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031116-44j60lx",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "開啟 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "發佈服務"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 開關"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-2v0lh0m",
|
||||
"Type": "NodeHeading",
|
||||
"HeadingLevel": 3,
|
||||
"Properties": {
|
||||
"id": "20240517031116-2v0lh0m",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "tag",
|
||||
"TextMarkTextContent": "注意"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-lx0pe26",
|
||||
"Type": "NodeList",
|
||||
"ListData": {},
|
||||
"Properties": {
|
||||
"id": "20240517031116-lx0pe26",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-kvje8ru",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031116-kvje8ru",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-gydcx3b",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031116-gydcx3b",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "開啟發佈服務後訪問者可以瀏覽整個工作空間的內容"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240517031116-ufsul2c",
|
||||
"Type": "NodeListItem",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Marker": "Kg=="
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240517031116-ufsul2c",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240517031116-xyb4012",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240517031116-xyb4012",
|
||||
"updated": "20240517031116"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "關閉 "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "服務 Basic 認證"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " 後所有的訪問者無需認證即可瀏覽整個工作空間的內容"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1 +1 @@
|
|||
{"20240530101000-0zd9si2":13,"20240530101000-1m5un7l":10,"20240530101000-1vvnhju":6,"20240530101000-35bbvcx":2,"20240530101000-3eaevtp":7,"20240530101000-3ourzoa":2,"20240530101000-3qhz7br":1,"20240530101000-3xv6jjr":9,"20240530101000-40hohog":19,"20240530101000-4cqkoel":23,"20240530101000-4p096e8":1,"20240530101000-4qitucx":1,"20240530101000-58z6rjh":2,"20240530101000-5gi76ax":8,"20240530101000-5k5d5i3":2,"20240530101000-6x9ivi7":11,"20240530101000-75auqcn":6,"20240530101000-78d5w10":4,"20240530101000-7yv4y5z":4,"20240530101000-875snki":7,"20240530101000-8m2dowc":9,"20240530101000-96n5y9v":1,"20240530101000-a91lmk2":3,"20240530101000-bb0qktp":1,"20240530101000-bgv304g":8,"20240530101000-boiita2":4,"20240530101000-bpj42r0":2,"20240530101000-cb37szr":7,"20240530101000-d31i9v5":2,"20240530101000-dro2zi9":5,"20240530101000-dytmky4":22,"20240530101000-e6z5okf":3,"20240530101000-ei5t6tt":17,"20240530101000-f16hpct":20,"20240530101000-flot1gj":7,"20240530101000-g3ugxml":5,"20240530101000-gc0tuyd":3,"20240530101000-gcdp3gl":3,"20240530101000-gvtksyj":1,"20240530101000-h0cp5vx":5,"20240530101000-hkgs92c":5,"20240530101000-hnu6o79":2,"20240530101000-hq9sn3k":1,"20240530101000-jp793ic":4,"20240530101000-mpln2lp":6,"20240530101000-mrlr6e9":4,"20240530101000-na9sys7":1,"20240530101000-odye3ea":3,"20240530101000-qf0xtkd":2,"20240530101000-scr2p21":5,"20240530101000-to5uvpi":12,"20240530101000-txrc7z1":15,"20240530101000-uxno1yp":3,"20240530101000-vejnh1k":1,"20240530101000-vql5s27":5,"20240530101000-wo49zvq":2,"20240530101000-xc13cm6":6,"20240530101000-xq26o73":21,"20240530101000-xr22qn8":4,"20240530101000-xsbxokr":18,"20240530101000-ynpmvl7":16,"20240530101000-zj4k048":3,"20240530101000-znj103k":10,"20240530101000-zprnpfi":14}
|
||||
{"20240530101000-0zd9si2":13,"20240530101000-1m5un7l":10,"20240530101000-1vvnhju":6,"20240530101000-35bbvcx":2,"20240530101000-3eaevtp":7,"20240530101000-3ourzoa":2,"20240530101000-3qhz7br":1,"20240530101000-3xv6jjr":9,"20240530101000-40hohog":19,"20240530101000-4cqkoel":23,"20240530101000-4p096e8":1,"20240530101000-4qitucx":1,"20240530101000-58z6rjh":2,"20240530101000-5gi76ax":8,"20240530101000-5k5d5i3":2,"20240530101000-6x9ivi7":11,"20240530101000-75auqcn":6,"20240530101000-78d5w10":4,"20240530101000-7yv4y5z":4,"20240530101000-875snki":7,"20240530101000-8m2dowc":9,"20240530101000-96n5y9v":1,"20240530101000-a91lmk2":3,"20240530101000-bb0qktp":1,"20240530101000-bgv304g":8,"20240530101000-boiita2":4,"20240530101000-bpj42r0":2,"20240530101000-cb37szr":7,"20240530101000-d31i9v5":2,"20240530101000-dro2zi9":5,"20240530101000-dytmky4":22,"20240530101000-e6z5okf":3,"20240530101000-ei5t6tt":17,"20240530101000-f16hpct":20,"20240530101000-flot1gj":7,"20240530101000-g3ugxml":5,"20240530101000-gc0tuyd":3,"20240530101000-gcdp3gl":3,"20240530101000-gvtksyj":1,"20240530101000-h0cp5vx":5,"20240530101000-hkgs92c":5,"20240530101000-hnu6o79":2,"20240530101000-hq9sn3k":1,"20240530101000-jp793ic":4,"20240530101000-mpln2lp":6,"20240530101000-mrlr6e9":4,"20240530101000-na9sys7":1,"20240530101000-odye3ea":3,"20240530101000-qf0xtkd":2,"20240530101000-scr2p21":5,"20240530101000-to5uvpi":12,"20240530101000-txrc7z1":15,"20240530101000-uxno1yp":3,"20240530101000-vejnh1k":1,"20240530101000-vql5s27":5,"20240530101000-wo49zvq":2,"20240530101000-xc13cm6":6,"20240530101000-xq26o73":21,"20240530101000-xr22qn8":4,"20240530101000-xsbxokr":18,"20240530101000-ynpmvl7":16,"20240530101000-zj4k048":3,"20240530101000-znj103k":10,"20240530101000-zprnpfi":14,"20240610233601-ylh1mvk":24}
|
|
@ -0,0 +1,676 @@
|
|||
{
|
||||
"ID": "20240610233601-ylh1mvk",
|
||||
"Spec": "1",
|
||||
"Type": "NodeDocument",
|
||||
"Properties": {
|
||||
"id": "20240610233601-ylh1mvk",
|
||||
"title": "サービスの公開",
|
||||
"type": "doc",
|
||||
"updated": "20240610235250"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-jjii9tu",
|
||||
"Type": "NodeHeading",
|
||||
"HeadingLevel": 2,
|
||||
"Properties": {
|
||||
"id": "20240610233629-jjii9tu",
|
||||
"updated": "20240610235250"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeHeadingC8hMarker",
|
||||
"Data": "## ",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "概要",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-49em84g",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240610233629-49em84g",
|
||||
"updated": "20240610233739"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "SiYuan Note は、現在のワークスペースの内容を読み取り専用モードでローカルネットワークで公開することができます。",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-bxuf2mx",
|
||||
"Type": "NodeHeading",
|
||||
"HeadingLevel": 2,
|
||||
"Properties": {
|
||||
"id": "20240610233629-bxuf2mx",
|
||||
"updated": "20240610235250"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "使い方"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-7d7e66r",
|
||||
"Type": "NodeList",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-7d7e66r",
|
||||
"updated": "20240610235250"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-jn7c5xq",
|
||||
"Type": "NodeListItem",
|
||||
"Data": "*",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-jn7c5xq",
|
||||
"updated": "20240610234354"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-ibn4bp6",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240610233629-ibn4bp6",
|
||||
"updated": "20240610234354"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ""
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "設定"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " - "
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "公開する"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " に移動して、公開サービスの設定パネルに入ります。"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-j8ml6bw",
|
||||
"Type": "NodeListItem",
|
||||
"Data": "*",
|
||||
"ListData": {
|
||||
"Tight": true,
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-j8ml6bw",
|
||||
"updated": "20240610234344"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-fubq5bz",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240610233629-fubq5bz",
|
||||
"updated": "20240610234344"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ""
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "サービスポート"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " を設定します。"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-d9q97le",
|
||||
"Type": "NodeList",
|
||||
"ListData": {
|
||||
"Tight": true,
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-d9q97le",
|
||||
"updated": "20240610233629"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-y8ynj1h",
|
||||
"Type": "NodeListItem",
|
||||
"Data": "*",
|
||||
"ListData": {
|
||||
"Tight": true,
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-y8ynj1h",
|
||||
"updated": "20240610233629"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-fwe6fgu",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240610233629-fwe6fgu",
|
||||
"updated": "20240610233629"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "デフォルトのポート番号は ",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
},
|
||||
"TextMarkType": "code",
|
||||
"TextMarkTextContent": "6808"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " です。",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-amkxqp8",
|
||||
"Type": "NodeListItem",
|
||||
"Data": "*",
|
||||
"ListData": {
|
||||
"Tight": true,
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-amkxqp8",
|
||||
"updated": "20240610233629"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-726ai0u",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240610233629-726ai0u",
|
||||
"updated": "20240610233629"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "ポート番号を ",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
},
|
||||
"TextMarkType": "code",
|
||||
"TextMarkTextContent": "0"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " に設定すると、ランダムなポートが使用されます。",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-c2bncke",
|
||||
"Type": "NodeListItem",
|
||||
"Data": "*",
|
||||
"ListData": {
|
||||
"Tight": true,
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-c2bncke",
|
||||
"updated": "20240610235250"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-c02853s",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240610233629-c02853s",
|
||||
"updated": "20240610233629"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "公開サービスにアクセス制限を設定する場合",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-a5alsxq",
|
||||
"Type": "NodeList",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-a5alsxq",
|
||||
"updated": "20240610235250"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-4p8jyop",
|
||||
"Type": "NodeListItem",
|
||||
"Data": "*",
|
||||
"ListData": {
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-4p8jyop",
|
||||
"updated": "20240610235142"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-6pki0nz",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240610233629-6pki0nz",
|
||||
"updated": "20240610235142"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ""
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "認証アカウント"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " を追加し、"
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "サービスの基本認証"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " スイッチをオンにします。"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-3s2kd31",
|
||||
"Type": "NodeListItem",
|
||||
"Data": "*",
|
||||
"ListData": {
|
||||
"Tight": true,
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-3s2kd31",
|
||||
"updated": "20240610235250"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-fozs5am",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240610233629-fozs5am",
|
||||
"updated": "20240610233721"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "この後、公開サービスはアクセスするユーザーを ",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
},
|
||||
"TextMarkType": "a",
|
||||
"TextMarkAHref": "https://developer.mozilla.org/ja/docs/Web/HTTP/Authentication#basic_認証方式",
|
||||
"TextMarkTextContent": "Basic 認証方式"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " を使用して認証します。",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-b18hlwj",
|
||||
"Type": "NodeList",
|
||||
"ListData": {
|
||||
"Tight": true,
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-b18hlwj",
|
||||
"updated": "20240610235250"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-4mziigo",
|
||||
"Type": "NodeListItem",
|
||||
"Data": "*",
|
||||
"ListData": {
|
||||
"Tight": true,
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-4mziigo",
|
||||
"updated": "20240610235250"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-526pequ",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240610233629-526pequ",
|
||||
"updated": "20240610235250"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "ユーザーは、公開コンテンツを閲覧する前に、"
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "認証アカウント"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " で設定したユーザー名とパスワードを正しく入力する必要があります。"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-a4d5gct",
|
||||
"Type": "NodeListItem",
|
||||
"Data": "*",
|
||||
"ListData": {
|
||||
"Tight": true,
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-a4d5gct",
|
||||
"updated": "20240610234926"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-cqspvm0",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240610233629-cqspvm0",
|
||||
"updated": "20240610234926"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ""
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "サービスを公開する"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " スイッチをオンにします"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-ns08k8s",
|
||||
"Type": "NodeHeading",
|
||||
"HeadingLevel": 2,
|
||||
"Properties": {
|
||||
"id": "20240610233629-ns08k8s",
|
||||
"updated": "20240610235147"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeHeadingC8hMarker",
|
||||
"Data": "## ",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
},
|
||||
"TextMarkType": "tag",
|
||||
"TextMarkTextContent": "注意事項"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-uqp9rz9",
|
||||
"Type": "NodeList",
|
||||
"ListData": {
|
||||
"Tight": true,
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-uqp9rz9",
|
||||
"updated": "20240610235147"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-jiv7u6m",
|
||||
"Type": "NodeListItem",
|
||||
"Data": "*",
|
||||
"ListData": {
|
||||
"Tight": true,
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-jiv7u6m",
|
||||
"updated": "20240610233629"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-j8ancdr",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240610233629-j8ancdr",
|
||||
"updated": "20240610233629"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": "公開サービスを開始すると、訪問者はワークスペースの全コンテンツを閲覧できます。",
|
||||
"Properties": {
|
||||
"id": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "20240610233629-10tmo1g",
|
||||
"Type": "NodeListItem",
|
||||
"Data": "*",
|
||||
"ListData": {
|
||||
"Tight": true,
|
||||
"BulletChar": 42,
|
||||
"Padding": 2,
|
||||
"Marker": "Kg==",
|
||||
"Num": -1
|
||||
},
|
||||
"Properties": {
|
||||
"id": "20240610233629-10tmo1g",
|
||||
"updated": "20240610235147"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"ID": "20240610233629-20lo5k4",
|
||||
"Type": "NodeParagraph",
|
||||
"Properties": {
|
||||
"id": "20240610233629-20lo5k4",
|
||||
"updated": "20240610235147"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": ""
|
||||
},
|
||||
{
|
||||
"Type": "NodeTextMark",
|
||||
"TextMarkType": "kbd",
|
||||
"TextMarkTextContent": "サービスの基本認証"
|
||||
},
|
||||
{
|
||||
"Type": "NodeText",
|
||||
"Data": " を無効にすると、すべての訪問者はワークスペースの全コンテンツを認証なしで閲覧できます。"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -310,10 +310,12 @@ export const editor = {
|
|||
if (fontFamilyElement.tagName === "SELECT") {
|
||||
let fontFamilyHTML = `<option value="">${window.siyuan.languages.default}</option>`;
|
||||
fetchPost("/api/system/getSysFonts", {}, (response) => {
|
||||
response.data.forEach((item: string) => {
|
||||
fontFamilyHTML += `<option value="${item}"${window.siyuan.config.editor.fontFamily === item ? " selected" : ""}>${item}</option>`;
|
||||
});
|
||||
fontFamilyElement.innerHTML = fontFamilyHTML;
|
||||
if (response.code === 0) {
|
||||
response.data.forEach((item: string) => {
|
||||
fontFamilyHTML += `<option value="${item}"${window.siyuan.config.editor.fontFamily === item ? " selected" : ""}>${item}</option>`;
|
||||
});
|
||||
fontFamilyElement.innerHTML = fontFamilyHTML;
|
||||
}
|
||||
});
|
||||
}
|
||||
editor.element.querySelector("#clearHistory").addEventListener("click", () => {
|
||||
|
|
|
@ -13,6 +13,7 @@ import {query} from "./query";
|
|||
import {Dialog} from "../dialog";
|
||||
import {ai} from "./ai";
|
||||
import {flashcard} from "./flashcard";
|
||||
import {publish} from "./publish";
|
||||
import {App} from "../index";
|
||||
import {isHuawei} from "../protyle/util/compatibility";
|
||||
import {Constants} from "../constants";
|
||||
|
@ -79,6 +80,11 @@ export const genItemPanel = (type: string, containerElement: Element, app: App)
|
|||
query.element = containerElement;
|
||||
query.bindEvent();
|
||||
break;
|
||||
case "publish":
|
||||
containerElement.innerHTML = publish.genHTML();
|
||||
publish.element = containerElement;
|
||||
publish.bindEvent();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -115,6 +121,7 @@ export const openSetting = (app: App) => {
|
|||
<li data-name="keymap" class="b3-list-item"><svg class="b3-list-item__graphic"><use xlink:href="#iconKeymap"></use></svg><span class="b3-list-item__text">${window.siyuan.languages.keymap}</span></li>
|
||||
<li data-name="account" class="b3-list-item"><svg class="b3-list-item__graphic"><use xlink:href="#iconAccount"></use></svg><span class="b3-list-item__text">${window.siyuan.languages.account}</span></li>
|
||||
<li data-name="repos" class="b3-list-item"><svg class="b3-list-item__graphic"><use xlink:href="#iconCloud"></use></svg><span class="b3-list-item__text">${window.siyuan.languages.cloud}</span></li>
|
||||
<li data-name="publish" class="b3-list-item"><svg class="b3-list-item__graphic"><use xlink:href="#iconLanguage"></use></svg><span class="b3-list-item__text">${window.siyuan.languages.publish}</span></li>
|
||||
<li data-name="about" class="b3-list-item"><svg class="b3-list-item__graphic"><use xlink:href="#iconInfo"></use></svg><span class="b3-list-item__text">${window.siyuan.languages.about}</span></li>
|
||||
</ul>
|
||||
<div class="config__tab-wrap">
|
||||
|
@ -131,6 +138,7 @@ export const openSetting = (app: App) => {
|
|||
<div class="config__tab-container fn__none" style="overflow: scroll" data-name="keymap"></div>
|
||||
<div class="config__tab-container config__tab-container--full fn__none" data-name="account"></div>
|
||||
<div class="config__tab-container fn__none" data-name="repos"></div>
|
||||
<div class="config__tab-container fn__none" data-name="publish"></div>
|
||||
<div class="config__tab-container fn__none" data-name="about"></div>
|
||||
<div class="fn__hr--b"></div>
|
||||
</div>
|
||||
|
|
213
app/src/config/publish.ts
Normal file
213
app/src/config/publish.ts
Normal file
|
@ -0,0 +1,213 @@
|
|||
import {hasClosestByMatchTag} from "../protyle/util/hasClosest";
|
||||
import {fetchPost} from "../util/fetch";
|
||||
|
||||
export const publish = {
|
||||
element: undefined as Element,
|
||||
genHTML: () => {
|
||||
return `
|
||||
<!-- publish service -->
|
||||
<label class="fn__flex b3-label">
|
||||
<div class="fn__flex-1">
|
||||
${window.siyuan.languages.publishService}
|
||||
<div class="b3-label__text">${window.siyuan.languages.publishServiceTip}</div>
|
||||
</div>
|
||||
<span class="fn__space"></span>
|
||||
<input class="b3-switch fn__flex-center" id="publishEnable" type="checkbox"${window.siyuan.config.publish.enable ? " checked" : ""}/>
|
||||
</label>
|
||||
|
||||
<div class="b3-label">
|
||||
<!-- publish service port -->
|
||||
<div class="fn__flex">
|
||||
<div class="fn__flex-1">
|
||||
${window.siyuan.languages.publishServicePort}
|
||||
<div class="b3-label__text">${window.siyuan.languages.publishServicePortTip}</div>
|
||||
</div>
|
||||
<span class="fn__space"></span>
|
||||
<input class="b3-text-field fn__flex-center fn__size200" id="publishPort" type="number" min="0" max="65535" value="${window.siyuan.config.publish.port}">
|
||||
</div>
|
||||
|
||||
<!-- publish service address list -->
|
||||
<div class="b3-label">
|
||||
<div class="fn__flex config__item">
|
||||
<div class="fn__flex-1">
|
||||
${window.siyuan.languages.publishServiceAddresses}
|
||||
<div class="b3-label__text">${window.siyuan.languages.publishServiceAddressesTip}</div>
|
||||
</div>
|
||||
<div class="fn__space"></div>
|
||||
</div>
|
||||
<div class="b3-label" id="publishAddresses">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="b3-label">
|
||||
<!-- publish service auth -->
|
||||
<label class="fn__flex">
|
||||
<div class="fn__flex-1">
|
||||
${window.siyuan.languages.publishServiceAuth}
|
||||
<div class="b3-label__text">${window.siyuan.languages.publishServiceAuthTip}</div>
|
||||
</div>
|
||||
<span class="fn__space"></span>
|
||||
<input class="b3-switch fn__flex-center" id="publishAuthEnable" type="checkbox"${window.siyuan.config.publish.auth.enable ? " checked" : ""}/>
|
||||
</label>
|
||||
|
||||
<!-- publish service auth accounts -->
|
||||
<div class="b3-label">
|
||||
<div class="fn__flex config__item">
|
||||
<div class="fn__flex-1">
|
||||
${window.siyuan.languages.publishServiceAuthAccounts}
|
||||
<div class="b3-label__text">${window.siyuan.languages.publishServiceAuthAccountsTip}</div>
|
||||
</div>
|
||||
<div class="fn__space"></div>
|
||||
<button class="b3-button b3-button--outline fn__size200 fn__flex-center" id="publishAuthAccountAdd">
|
||||
<svg><use xlink:href="#iconAdd"></use></svg>${window.siyuan.languages.publishServiceAuthAccountAdd}
|
||||
</button>
|
||||
</div>
|
||||
<div class="fn__flex" id="publishAuthAccounts">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
},
|
||||
bindEvent: () => {
|
||||
const publishAuthAccountAdd = publish.element.querySelector<HTMLButtonElement>("#publishAuthAccountAdd");
|
||||
|
||||
/* add account */
|
||||
publishAuthAccountAdd.addEventListener("click", () => {
|
||||
window.siyuan.config.publish.auth.accounts.push({
|
||||
username: "",
|
||||
password: "",
|
||||
memo: "",
|
||||
});
|
||||
publish._renderPublishAuthAccounts(publish.element);
|
||||
});
|
||||
|
||||
/* input change */
|
||||
publish.element.querySelectorAll("input").forEach(item => {
|
||||
item.addEventListener("change", () => {
|
||||
publish._savePublish();
|
||||
});
|
||||
});
|
||||
|
||||
publish._refreshPublish();
|
||||
},
|
||||
_refreshPublish: () => {
|
||||
fetchPost("/api/setting/getPublish", {}, publish._updatePublishConfig.bind(null, true));
|
||||
},
|
||||
_savePublish: (reloadAccounts = true) => {
|
||||
const publishEnable = publish.element.querySelector<HTMLInputElement>("#publishEnable");
|
||||
const publishPort = publish.element.querySelector<HTMLInputElement>("#publishPort");
|
||||
const publishAuthEnable = publish.element.querySelector<HTMLInputElement>("#publishAuthEnable");
|
||||
|
||||
fetchPost("/api/setting/setPublish", {
|
||||
enable: publishEnable.checked,
|
||||
port: publishPort.valueAsNumber,
|
||||
auth: {
|
||||
enable: publishAuthEnable.checked,
|
||||
accounts: window.siyuan.config.publish.auth.accounts,
|
||||
} as Config.IPublishAuth,
|
||||
} as Config.IPublish, publish._updatePublishConfig.bind(null, reloadAccounts));
|
||||
},
|
||||
_updatePublishConfig: (
|
||||
reloadAccounts: boolean,
|
||||
response: IWebSocketData,
|
||||
) => {
|
||||
if (response.code === 0) {
|
||||
window.siyuan.config.publish = response.data.publish;
|
||||
|
||||
reloadAccounts && publish._renderPublishAuthAccounts(publish.element);
|
||||
publish._renderPublishAddressList(publish.element, response.data.port);
|
||||
} else {
|
||||
publish._renderPublishAddressList(publish.element, 0);
|
||||
}
|
||||
},
|
||||
_renderPublishAuthAccounts: (
|
||||
element: Element,
|
||||
accounts: Config.IPublishAuthAccount[] = window.siyuan.config.publish.auth.accounts,
|
||||
) => {
|
||||
const publishAuthAccounts = element.querySelector<HTMLDivElement>("#publishAuthAccounts");
|
||||
publishAuthAccounts.innerHTML = `<ul class="fn__flex-1" style="margin-top: 16px">${
|
||||
accounts
|
||||
.map((account, index) => `
|
||||
<li class="b3-label--inner fn__flex" data-index="${index}">
|
||||
<input class="b3-text-field fn__block" data-name="username" value="${account.username}" placeholder="${window.siyuan.languages.userName}">
|
||||
<span class="fn__space"></span>
|
||||
<div class="b3-form__icona fn__block">
|
||||
<input class="b3-text-field fn__block b3-form__icona-input" type="password" data-name="password" value="${account.password}" placeholder="${window.siyuan.languages.password}">
|
||||
<svg class="b3-form__icona-icon" data-action="togglePassword"><use xlink:href="#iconEye"></use></svg>
|
||||
</div>
|
||||
<span class="fn__space"></span>
|
||||
<input class="b3-text-field fn__block" data-name="memo" value="${account.memo}" placeholder="${window.siyuan.languages.memo}">
|
||||
<span class="fn__space"></span>
|
||||
<span data-action="remove" class="block__icon block__icon--show">
|
||||
<svg><use xlink:href="#iconTrashcan"></use></svg>
|
||||
</span>
|
||||
</li>`
|
||||
)
|
||||
.join("")
|
||||
}</ul>`;
|
||||
|
||||
/* account field changed */
|
||||
publishAuthAccounts
|
||||
.querySelectorAll("input")
|
||||
.forEach(input => {
|
||||
input.addEventListener("change", () => {
|
||||
const li = hasClosestByMatchTag(input, "LI");
|
||||
if (li) {
|
||||
const index = parseInt(li.dataset.index);
|
||||
const name = input.dataset.name as keyof Config.IPublishAuthAccount;
|
||||
if (name in window.siyuan.config.publish.auth.accounts[index]) {
|
||||
window.siyuan.config.publish.auth.accounts[index][name] = input.value;
|
||||
publish._savePublish(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/* delete account */
|
||||
publishAuthAccounts
|
||||
.querySelectorAll('.block__icon[data-action="remove"]')
|
||||
.forEach(remove => {
|
||||
remove.addEventListener("click", () => {
|
||||
const li = hasClosestByMatchTag(remove, "LI");
|
||||
if (li) {
|
||||
const index = parseInt(li.dataset.index);
|
||||
window.siyuan.config.publish.auth.accounts.splice(index, 1);
|
||||
publish._savePublish();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/* Toggle the password display status */
|
||||
publishAuthAccounts
|
||||
.querySelectorAll('.b3-form__icona-icon[data-action="togglePassword"]')
|
||||
.forEach(togglePassword => {
|
||||
togglePassword.addEventListener("click", () => {
|
||||
const isEye = togglePassword.firstElementChild.getAttribute("xlink:href") === "#iconEye";
|
||||
togglePassword.firstElementChild.setAttribute("xlink:href", isEye ? "#iconEyeoff" : "#iconEye");
|
||||
togglePassword.previousElementSibling.setAttribute("type", isEye ? "text" : "password");
|
||||
});
|
||||
});
|
||||
},
|
||||
_renderPublishAddressList: (
|
||||
element: Element,
|
||||
port: number,
|
||||
) => {
|
||||
const publishAddresses = element.querySelector<HTMLDivElement>("#publishAddresses");
|
||||
if (port === 0) {
|
||||
publishAddresses.innerText = window.siyuan.languages.publishServiceNotStarted;
|
||||
} else {
|
||||
publishAddresses.innerHTML = `<ul class="b3-list b3-list--background fn__flex-1">${
|
||||
window.siyuan.config.localIPs
|
||||
.filter(ip => !(ip.startsWith("[") && ip.endsWith("]")))
|
||||
.map(ip => `<li><code class="fn__code">${ip}:${port}</code></li>`)
|
||||
.join("")
|
||||
}${
|
||||
window.siyuan.config.localIPs
|
||||
.filter(ip => (ip.startsWith("[") && ip.endsWith("]")))
|
||||
.map(ip => `<li><code class="fn__code">${ip}:${port}</code></li>`)
|
||||
.join("")
|
||||
}</ul>`;
|
||||
}
|
||||
},
|
||||
}
|
|
@ -169,13 +169,17 @@ const dockToJSON = (dock: Dock) => {
|
|||
};
|
||||
|
||||
export const resetLayout = () => {
|
||||
fetchPost("/api/system/setUILayout", {layout: {}}, () => {
|
||||
window.siyuan.storage[Constants.LOCAL_FILEPOSITION] = {};
|
||||
setStorageVal(Constants.LOCAL_FILEPOSITION, window.siyuan.storage[Constants.LOCAL_FILEPOSITION]);
|
||||
window.siyuan.storage[Constants.LOCAL_DIALOGPOSITION] = {};
|
||||
setStorageVal(Constants.LOCAL_DIALOGPOSITION, window.siyuan.storage[Constants.LOCAL_DIALOGPOSITION]);
|
||||
if (window.siyuan.config.readonly) {
|
||||
window.location.reload();
|
||||
});
|
||||
} else {
|
||||
fetchPost("/api/system/setUILayout", {layout: {}}, () => {
|
||||
window.siyuan.storage[Constants.LOCAL_FILEPOSITION] = {};
|
||||
setStorageVal(Constants.LOCAL_FILEPOSITION, window.siyuan.storage[Constants.LOCAL_FILEPOSITION]);
|
||||
window.siyuan.storage[Constants.LOCAL_DIALOGPOSITION] = {};
|
||||
setStorageVal(Constants.LOCAL_DIALOGPOSITION, window.siyuan.storage[Constants.LOCAL_DIALOGPOSITION]);
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let saveCount = 0;
|
||||
|
@ -211,10 +215,12 @@ export const saveLayout = () => {
|
|||
if (isWindow()) {
|
||||
sessionStorage.setItem("layout", JSON.stringify(layoutJSON));
|
||||
} else {
|
||||
fetchPost("/api/system/setUILayout", {
|
||||
layout: layoutJSON,
|
||||
errorExit: false // 后台不接受该参数,用于请求发生错误时退出程序
|
||||
});
|
||||
if (!window.siyuan.config.readonly) {
|
||||
fetchPost("/api/system/setUILayout", {
|
||||
layout: layoutJSON,
|
||||
errorExit: false // 后台不接受该参数,用于请求发生错误时退出程序
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -250,12 +256,17 @@ export const exportLayout = (options: {
|
|||
getAllModels().editor.forEach(item => {
|
||||
saveScroll(item.editor.protyle);
|
||||
});
|
||||
fetchPost("/api/system/setUILayout", {
|
||||
layout: layoutJSON,
|
||||
errorExit: options.errorExit // 后台不接受该参数,用于请求发生错误时退出程序
|
||||
}, () => {
|
||||
|
||||
if (window.siyuan.config.readonly) {
|
||||
options.cb();
|
||||
});
|
||||
} else {
|
||||
fetchPost("/api/system/setUILayout", {
|
||||
layout: layoutJSON,
|
||||
errorExit: options.errorExit // 后台不接受该参数,用于请求发生错误时退出程序
|
||||
}, () => {
|
||||
options.cb();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const getAllLayout = () => {
|
||||
|
|
|
@ -507,8 +507,9 @@ export const exportMd = (id: string) => {
|
|||
});
|
||||
});
|
||||
return;
|
||||
} else if (response.code === 0) {
|
||||
showMessage(window.siyuan.languages.exportTplSucc);
|
||||
}
|
||||
showMessage(window.siyuan.languages.exportTplSucc);
|
||||
});
|
||||
dialog.destroy();
|
||||
});
|
||||
|
|
|
@ -340,9 +340,13 @@ export const workspaceMenu = (app: App, rect: DOMRect) => {
|
|||
window.siyuan.menus.menu.remove();
|
||||
return;
|
||||
}
|
||||
fetchPost("/api/system/setUILayout", {layout: item.layout}, () => {
|
||||
if (window.siyuan.config.readonly) {
|
||||
window.location.reload();
|
||||
});
|
||||
} else {
|
||||
fetchPost("/api/system/setUILayout", {layout: item.layout}, () => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -287,6 +287,10 @@ export const getLocalStorage = (cb: () => void) => {
|
|||
};
|
||||
|
||||
export const setStorageVal = (key: string, val: any) => {
|
||||
if (window.siyuan.config.readonly) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetchPost("/api/storage/setLocalStorageVal", {
|
||||
app: Constants.SIYUAN_APPID,
|
||||
key,
|
||||
|
|
55
app/src/types/config.d.ts
vendored
55
app/src/types/config.d.ts
vendored
|
@ -63,6 +63,11 @@ declare namespace Config {
|
|||
* Whether to open the user guide after startup
|
||||
*/
|
||||
openHelp: boolean;
|
||||
/**
|
||||
* Publishing service
|
||||
* 发布服务
|
||||
*/
|
||||
publish: IPublish;
|
||||
/**
|
||||
* Whether it is running in read-only mode
|
||||
* 全局只读
|
||||
|
@ -1030,6 +1035,56 @@ declare namespace Config {
|
|||
*/
|
||||
export type TLogLevel = "off" | "trace" | "debug" | "info" | "warn" | "error" | "fatal";
|
||||
|
||||
/**
|
||||
* Publishing service
|
||||
*/
|
||||
export interface IPublish {
|
||||
/**
|
||||
* Whether to open the publishing service
|
||||
*/
|
||||
enable: boolean;
|
||||
/**
|
||||
* The basic authentication settings of publishing service
|
||||
*/
|
||||
auth: IPublishAuth;
|
||||
/**
|
||||
* Port on which the publishing service listens
|
||||
*/
|
||||
port: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishing service authentication settings
|
||||
*/
|
||||
export interface IPublishAuth {
|
||||
/**
|
||||
* Whether to enable basic authentication for publishing services
|
||||
*/
|
||||
enable: boolean;
|
||||
/**
|
||||
* List of basic verified accounts
|
||||
*/
|
||||
accounts: IPublishAuthAccount[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic authentication account
|
||||
*/
|
||||
export interface IPublishAuthAccount {
|
||||
/**
|
||||
* Account username
|
||||
*/
|
||||
username: string;
|
||||
/**
|
||||
* Account password
|
||||
*/
|
||||
password: string;
|
||||
/**
|
||||
* The memo text of the account
|
||||
*/
|
||||
memo: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Snapshot repository related configuration
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -32,18 +32,20 @@ export const fetchPost = (url: string, data?: any, cb?: (response: IWebSocketDat
|
|||
init.headers = headers;
|
||||
}
|
||||
fetch(url, init).then((response) => {
|
||||
if (response.status === 404) {
|
||||
return {
|
||||
data: null,
|
||||
msg: response.statusText,
|
||||
code: response.status,
|
||||
};
|
||||
} else {
|
||||
if (response.headers.get("content-type")?.indexOf("application/json") > -1) {
|
||||
return response.json();
|
||||
} else {
|
||||
return response.text();
|
||||
}
|
||||
switch (response.status) {
|
||||
case 403:
|
||||
case 404:
|
||||
return {
|
||||
data: null,
|
||||
msg: response.statusText,
|
||||
code: response.status,
|
||||
};
|
||||
default:
|
||||
if (response.headers.get("content-type")?.indexOf("application/json") > -1) {
|
||||
return response.json();
|
||||
} else {
|
||||
return response.text();
|
||||
}
|
||||
}
|
||||
}).then((response: IWebSocketData) => {
|
||||
if (typeof response === "string") {
|
||||
|
|
|
@ -166,13 +166,31 @@ func getFile(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
if info.IsDir() {
|
||||
logging.LogErrorf("file [%s] is a directory", fileAbsPath)
|
||||
logging.LogErrorf("path [%s] is a directory path", fileAbsPath)
|
||||
ret.Code = http.StatusMethodNotAllowed
|
||||
ret.Msg = "file is a directory"
|
||||
ret.Msg = "This is a directory path"
|
||||
c.JSON(http.StatusAccepted, ret)
|
||||
return
|
||||
}
|
||||
|
||||
// REF: https://github.com/siyuan-note/siyuan/issues/11364
|
||||
if role := model.GetGinContextRole(c); !model.IsValidRole(role, []model.Role{
|
||||
model.RoleAdministrator,
|
||||
}) {
|
||||
if relPath, err := filepath.Rel(util.ConfDir, fileAbsPath); err != nil {
|
||||
logging.LogErrorf("Get a relative path from [%s] to [%s] failed: %s", util.ConfDir, fileAbsPath, err)
|
||||
ret.Code = http.StatusInternalServerError
|
||||
ret.Msg = err.Error()
|
||||
c.JSON(http.StatusAccepted, ret)
|
||||
return
|
||||
} else if relPath == "conf.json" {
|
||||
ret.Code = http.StatusForbidden
|
||||
ret.Msg = http.StatusText(http.StatusForbidden)
|
||||
c.JSON(http.StatusAccepted, ret)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
data, err := filelock.ReadFile(fileAbsPath)
|
||||
if nil != err {
|
||||
logging.LogErrorf("read file [%s] failed: %s", fileAbsPath, err)
|
||||
|
|
|
@ -33,122 +33,121 @@ func ServeAPI(ginServer *gin.Engine) {
|
|||
ginServer.Handle("POST", "/api/system/loginAuth", model.LoginAuth)
|
||||
ginServer.Handle("POST", "/api/system/logoutAuth", model.LogoutAuth)
|
||||
ginServer.Handle("GET", "/api/system/getCaptcha", model.GetCaptcha)
|
||||
ginServer.Handle("POST", "/api/system/setUILayout", setUILayout) // 这里不加鉴权 After modifying the access authentication code on the browser side, the other side does not refresh https://github.com/siyuan-note/siyuan/issues/8028
|
||||
ginServer.Handle("GET", "/snippets/*filepath", serveSnippets)
|
||||
|
||||
// 需要鉴权
|
||||
|
||||
ginServer.Handle("POST", "/api/system/getEmojiConf", model.CheckAuth, getEmojiConf)
|
||||
ginServer.Handle("POST", "/api/system/setAPIToken", model.CheckAuth, model.CheckReadonly, setAPIToken)
|
||||
ginServer.Handle("POST", "/api/system/setAccessAuthCode", model.CheckAuth, model.CheckReadonly, setAccessAuthCode)
|
||||
ginServer.Handle("POST", "/api/system/setFollowSystemLockScreen", model.CheckAuth, model.CheckReadonly, setFollowSystemLockScreen)
|
||||
ginServer.Handle("POST", "/api/system/setNetworkServe", model.CheckAuth, model.CheckReadonly, setNetworkServe)
|
||||
ginServer.Handle("POST", "/api/system/setUploadErrLog", model.CheckAuth, model.CheckReadonly, setUploadErrLog)
|
||||
ginServer.Handle("POST", "/api/system/setAutoLaunch", model.CheckAuth, model.CheckReadonly, setAutoLaunch)
|
||||
ginServer.Handle("POST", "/api/system/setGoogleAnalytics", model.CheckAuth, model.CheckReadonly, setGoogleAnalytics)
|
||||
ginServer.Handle("POST", "/api/system/setDownloadInstallPkg", model.CheckAuth, model.CheckReadonly, setDownloadInstallPkg)
|
||||
ginServer.Handle("POST", "/api/system/setNetworkProxy", model.CheckAuth, model.CheckReadonly, setNetworkProxy)
|
||||
ginServer.Handle("POST", "/api/system/setWorkspaceDir", model.CheckAuth, model.CheckReadonly, setWorkspaceDir)
|
||||
ginServer.Handle("POST", "/api/system/getWorkspaces", model.CheckAuth, getWorkspaces)
|
||||
ginServer.Handle("POST", "/api/system/getMobileWorkspaces", model.CheckAuth, getMobileWorkspaces)
|
||||
ginServer.Handle("POST", "/api/system/checkWorkspaceDir", model.CheckAuth, model.CheckReadonly, checkWorkspaceDir)
|
||||
ginServer.Handle("POST", "/api/system/createWorkspaceDir", model.CheckAuth, model.CheckReadonly, createWorkspaceDir)
|
||||
ginServer.Handle("POST", "/api/system/removeWorkspaceDir", model.CheckAuth, model.CheckReadonly, removeWorkspaceDir)
|
||||
ginServer.Handle("POST", "/api/system/removeWorkspaceDirPhysically", model.CheckAuth, model.CheckReadonly, removeWorkspaceDirPhysically)
|
||||
ginServer.Handle("POST", "/api/system/setAppearanceMode", model.CheckAuth, setAppearanceMode)
|
||||
ginServer.Handle("POST", "/api/system/getSysFonts", model.CheckAuth, getSysFonts)
|
||||
ginServer.Handle("POST", "/api/system/exit", model.CheckAuth, exit)
|
||||
ginServer.Handle("POST", "/api/system/setAPIToken", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setAPIToken)
|
||||
ginServer.Handle("POST", "/api/system/setAccessAuthCode", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setAccessAuthCode)
|
||||
ginServer.Handle("POST", "/api/system/setFollowSystemLockScreen", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setFollowSystemLockScreen)
|
||||
ginServer.Handle("POST", "/api/system/setNetworkServe", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setNetworkServe)
|
||||
ginServer.Handle("POST", "/api/system/setUploadErrLog", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setUploadErrLog)
|
||||
ginServer.Handle("POST", "/api/system/setAutoLaunch", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setAutoLaunch)
|
||||
ginServer.Handle("POST", "/api/system/setGoogleAnalytics", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setGoogleAnalytics)
|
||||
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/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)
|
||||
ginServer.Handle("POST", "/api/system/removeWorkspaceDir", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeWorkspaceDir)
|
||||
ginServer.Handle("POST", "/api/system/removeWorkspaceDirPhysically", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeWorkspaceDirPhysically)
|
||||
ginServer.Handle("POST", "/api/system/setAppearanceMode", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setAppearanceMode)
|
||||
ginServer.Handle("POST", "/api/system/setUILayout", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setUILayout)
|
||||
ginServer.Handle("POST", "/api/system/getSysFonts", model.CheckAuth, model.CheckAdminRole, getSysFonts)
|
||||
ginServer.Handle("POST", "/api/system/exit", model.CheckAuth, model.CheckAdminRole, exit)
|
||||
ginServer.Handle("POST", "/api/system/getConf", model.CheckAuth, getConf)
|
||||
ginServer.Handle("POST", "/api/system/checkUpdate", model.CheckAuth, checkUpdate)
|
||||
ginServer.Handle("POST", "/api/system/exportLog", model.CheckAuth, exportLog)
|
||||
ginServer.Handle("POST", "/api/system/checkUpdate", model.CheckAuth, model.CheckAdminRole, checkUpdate)
|
||||
ginServer.Handle("POST", "/api/system/exportLog", model.CheckAuth, model.CheckAdminRole, exportLog)
|
||||
ginServer.Handle("POST", "/api/system/getChangelog", model.CheckAuth, getChangelog)
|
||||
ginServer.Handle("POST", "/api/system/getNetwork", model.CheckAuth, getNetwork)
|
||||
ginServer.Handle("POST", "/api/system/getNetwork", model.CheckAuth, model.CheckAdminRole, getNetwork)
|
||||
|
||||
ginServer.Handle("POST", "/api/storage/setLocalStorage", model.CheckAuth, model.CheckReadonly, setLocalStorage)
|
||||
ginServer.Handle("POST", "/api/storage/setLocalStorage", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setLocalStorage)
|
||||
ginServer.Handle("POST", "/api/storage/getLocalStorage", model.CheckAuth, getLocalStorage)
|
||||
ginServer.Handle("POST", "/api/storage/setLocalStorageVal", model.CheckAuth, model.CheckReadonly, setLocalStorageVal)
|
||||
ginServer.Handle("POST", "/api/storage/removeLocalStorageVals", model.CheckAuth, model.CheckReadonly, removeLocalStorageVals)
|
||||
ginServer.Handle("POST", "/api/storage/setCriterion", model.CheckAuth, model.CheckReadonly, setCriterion)
|
||||
ginServer.Handle("POST", "/api/storage/setLocalStorageVal", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setLocalStorageVal)
|
||||
ginServer.Handle("POST", "/api/storage/removeLocalStorageVals", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeLocalStorageVals)
|
||||
ginServer.Handle("POST", "/api/storage/setCriterion", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setCriterion)
|
||||
ginServer.Handle("POST", "/api/storage/getCriteria", model.CheckAuth, getCriteria)
|
||||
ginServer.Handle("POST", "/api/storage/removeCriterion", model.CheckAuth, model.CheckReadonly, removeCriterion)
|
||||
ginServer.Handle("POST", "/api/storage/removeCriterion", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeCriterion)
|
||||
ginServer.Handle("POST", "/api/storage/getRecentDocs", model.CheckAuth, getRecentDocs)
|
||||
|
||||
ginServer.Handle("POST", "/api/account/login", model.CheckAuth, model.CheckReadonly, login)
|
||||
ginServer.Handle("POST", "/api/account/checkActivationcode", model.CheckAuth, model.CheckReadonly, checkActivationcode)
|
||||
ginServer.Handle("POST", "/api/account/useActivationcode", model.CheckAuth, model.CheckReadonly, useActivationcode)
|
||||
ginServer.Handle("POST", "/api/account/deactivate", model.CheckAuth, model.CheckReadonly, deactivateUser)
|
||||
ginServer.Handle("POST", "/api/account/startFreeTrial", model.CheckAuth, model.CheckReadonly, startFreeTrial)
|
||||
ginServer.Handle("POST", "/api/account/login", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, login)
|
||||
ginServer.Handle("POST", "/api/account/checkActivationcode", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, checkActivationcode)
|
||||
ginServer.Handle("POST", "/api/account/useActivationcode", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, useActivationcode)
|
||||
ginServer.Handle("POST", "/api/account/deactivate", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, deactivateUser)
|
||||
ginServer.Handle("POST", "/api/account/startFreeTrial", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, startFreeTrial)
|
||||
|
||||
ginServer.Handle("POST", "/api/notebook/lsNotebooks", model.CheckAuth, lsNotebooks)
|
||||
ginServer.Handle("POST", "/api/notebook/openNotebook", model.CheckAuth, model.CheckReadonly, openNotebook)
|
||||
ginServer.Handle("POST", "/api/notebook/closeNotebook", model.CheckAuth, model.CheckReadonly, closeNotebook)
|
||||
ginServer.Handle("POST", "/api/notebook/openNotebook", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, openNotebook)
|
||||
ginServer.Handle("POST", "/api/notebook/closeNotebook", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, closeNotebook)
|
||||
ginServer.Handle("POST", "/api/notebook/getNotebookConf", model.CheckAuth, getNotebookConf)
|
||||
ginServer.Handle("POST", "/api/notebook/setNotebookConf", model.CheckAuth, model.CheckReadonly, setNotebookConf)
|
||||
ginServer.Handle("POST", "/api/notebook/createNotebook", model.CheckAuth, model.CheckReadonly, createNotebook)
|
||||
ginServer.Handle("POST", "/api/notebook/removeNotebook", model.CheckAuth, model.CheckReadonly, removeNotebook)
|
||||
ginServer.Handle("POST", "/api/notebook/renameNotebook", model.CheckAuth, model.CheckReadonly, renameNotebook)
|
||||
ginServer.Handle("POST", "/api/notebook/changeSortNotebook", model.CheckAuth, model.CheckReadonly, changeSortNotebook)
|
||||
ginServer.Handle("POST", "/api/notebook/setNotebookIcon", model.CheckAuth, model.CheckReadonly, setNotebookIcon)
|
||||
ginServer.Handle("POST", "/api/notebook/setNotebookConf", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setNotebookConf)
|
||||
ginServer.Handle("POST", "/api/notebook/createNotebook", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, createNotebook)
|
||||
ginServer.Handle("POST", "/api/notebook/removeNotebook", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeNotebook)
|
||||
ginServer.Handle("POST", "/api/notebook/renameNotebook", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, renameNotebook)
|
||||
ginServer.Handle("POST", "/api/notebook/changeSortNotebook", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, changeSortNotebook)
|
||||
ginServer.Handle("POST", "/api/notebook/setNotebookIcon", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setNotebookIcon)
|
||||
|
||||
ginServer.Handle("POST", "/api/filetree/searchDocs", model.CheckAuth, searchDocs)
|
||||
ginServer.Handle("POST", "/api/filetree/listDocsByPath", model.CheckAuth, listDocsByPath)
|
||||
ginServer.Handle("POST", "/api/filetree/getDoc", model.CheckAuth, getDoc)
|
||||
ginServer.Handle("POST", "/api/filetree/getDocCreateSavePath", model.CheckAuth, getDocCreateSavePath)
|
||||
ginServer.Handle("POST", "/api/filetree/getRefCreateSavePath", model.CheckAuth, getRefCreateSavePath)
|
||||
ginServer.Handle("POST", "/api/filetree/changeSort", model.CheckAuth, model.CheckReadonly, changeSort)
|
||||
ginServer.Handle("POST", "/api/filetree/createDocWithMd", model.CheckAuth, model.CheckReadonly, createDocWithMd)
|
||||
ginServer.Handle("POST", "/api/filetree/createDailyNote", model.CheckAuth, model.CheckReadonly, createDailyNote)
|
||||
ginServer.Handle("POST", "/api/filetree/createDoc", model.CheckAuth, model.CheckReadonly, createDoc)
|
||||
ginServer.Handle("POST", "/api/filetree/renameDoc", model.CheckAuth, model.CheckReadonly, renameDoc)
|
||||
ginServer.Handle("POST", "/api/filetree/removeDoc", model.CheckAuth, model.CheckReadonly, removeDoc)
|
||||
ginServer.Handle("POST", "/api/filetree/removeDocs", model.CheckAuth, model.CheckReadonly, removeDocs)
|
||||
ginServer.Handle("POST", "/api/filetree/moveDocs", model.CheckAuth, model.CheckReadonly, moveDocs)
|
||||
ginServer.Handle("POST", "/api/filetree/duplicateDoc", model.CheckAuth, model.CheckReadonly, duplicateDoc)
|
||||
ginServer.Handle("POST", "/api/filetree/changeSort", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, changeSort)
|
||||
ginServer.Handle("POST", "/api/filetree/createDocWithMd", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, createDocWithMd)
|
||||
ginServer.Handle("POST", "/api/filetree/createDailyNote", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, createDailyNote)
|
||||
ginServer.Handle("POST", "/api/filetree/createDoc", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, createDoc)
|
||||
ginServer.Handle("POST", "/api/filetree/renameDoc", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, renameDoc)
|
||||
ginServer.Handle("POST", "/api/filetree/removeDoc", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeDoc)
|
||||
ginServer.Handle("POST", "/api/filetree/removeDocs", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeDocs)
|
||||
ginServer.Handle("POST", "/api/filetree/moveDocs", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, moveDocs)
|
||||
ginServer.Handle("POST", "/api/filetree/duplicateDoc", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, duplicateDoc)
|
||||
ginServer.Handle("POST", "/api/filetree/getHPathByPath", model.CheckAuth, getHPathByPath)
|
||||
ginServer.Handle("POST", "/api/filetree/getHPathsByPaths", model.CheckAuth, getHPathsByPaths)
|
||||
ginServer.Handle("POST", "/api/filetree/getHPathByID", model.CheckAuth, getHPathByID)
|
||||
ginServer.Handle("POST", "/api/filetree/getFullHPathByID", model.CheckAuth, getFullHPathByID)
|
||||
ginServer.Handle("POST", "/api/filetree/getIDsByHPath", model.CheckAuth, getIDsByHPath)
|
||||
ginServer.Handle("POST", "/api/filetree/doc2Heading", model.CheckAuth, model.CheckReadonly, doc2Heading)
|
||||
ginServer.Handle("POST", "/api/filetree/heading2Doc", model.CheckAuth, model.CheckReadonly, heading2Doc)
|
||||
ginServer.Handle("POST", "/api/filetree/li2Doc", model.CheckAuth, model.CheckReadonly, li2Doc)
|
||||
ginServer.Handle("POST", "/api/filetree/refreshFiletree", model.CheckAuth, model.CheckReadonly, refreshFiletree)
|
||||
ginServer.Handle("POST", "/api/filetree/upsertIndexes", model.CheckAuth, model.CheckReadonly, upsertIndexes)
|
||||
ginServer.Handle("POST", "/api/filetree/removeIndexes", model.CheckAuth, model.CheckReadonly, removeIndexes)
|
||||
ginServer.Handle("POST", "/api/filetree/listDocTree", model.CheckAuth, model.CheckReadonly, listDocTree)
|
||||
ginServer.Handle("POST", "/api/filetree/doc2Heading", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, doc2Heading)
|
||||
ginServer.Handle("POST", "/api/filetree/heading2Doc", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, heading2Doc)
|
||||
ginServer.Handle("POST", "/api/filetree/li2Doc", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, li2Doc)
|
||||
ginServer.Handle("POST", "/api/filetree/refreshFiletree", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, refreshFiletree)
|
||||
ginServer.Handle("POST", "/api/filetree/upsertIndexes", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, upsertIndexes)
|
||||
ginServer.Handle("POST", "/api/filetree/removeIndexes", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeIndexes)
|
||||
ginServer.Handle("POST", "/api/filetree/listDocTree", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, listDocTree)
|
||||
|
||||
ginServer.Handle("POST", "/api/format/autoSpace", model.CheckAuth, model.CheckReadonly, autoSpace)
|
||||
ginServer.Handle("POST", "/api/format/netImg2LocalAssets", model.CheckAuth, model.CheckReadonly, netImg2LocalAssets)
|
||||
ginServer.Handle("POST", "/api/format/netAssets2LocalAssets", model.CheckAuth, model.CheckReadonly, netAssets2LocalAssets)
|
||||
ginServer.Handle("POST", "/api/format/autoSpace", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, autoSpace)
|
||||
ginServer.Handle("POST", "/api/format/netImg2LocalAssets", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, netImg2LocalAssets)
|
||||
ginServer.Handle("POST", "/api/format/netAssets2LocalAssets", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, netAssets2LocalAssets)
|
||||
|
||||
ginServer.Handle("POST", "/api/history/getNotebookHistory", model.CheckAuth, getNotebookHistory)
|
||||
ginServer.Handle("POST", "/api/history/rollbackNotebookHistory", model.CheckAuth, model.CheckReadonly, rollbackNotebookHistory)
|
||||
ginServer.Handle("POST", "/api/history/rollbackAssetsHistory", model.CheckAuth, model.CheckReadonly, rollbackAssetsHistory)
|
||||
ginServer.Handle("POST", "/api/history/getDocHistoryContent", model.CheckAuth, getDocHistoryContent)
|
||||
ginServer.Handle("POST", "/api/history/rollbackDocHistory", model.CheckAuth, model.CheckReadonly, rollbackDocHistory)
|
||||
ginServer.Handle("POST", "/api/history/clearWorkspaceHistory", model.CheckAuth, model.CheckReadonly, clearWorkspaceHistory)
|
||||
ginServer.Handle("POST", "/api/history/reindexHistory", model.CheckAuth, model.CheckReadonly, reindexHistory)
|
||||
ginServer.Handle("POST", "/api/history/searchHistory", model.CheckAuth, searchHistory)
|
||||
ginServer.Handle("POST", "/api/history/getHistoryItems", model.CheckAuth, getHistoryItems)
|
||||
ginServer.Handle("POST", "/api/history/getNotebookHistory", model.CheckAuth, model.CheckAdminRole, getNotebookHistory)
|
||||
ginServer.Handle("POST", "/api/history/rollbackNotebookHistory", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, rollbackNotebookHistory)
|
||||
ginServer.Handle("POST", "/api/history/rollbackAssetsHistory", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, rollbackAssetsHistory)
|
||||
ginServer.Handle("POST", "/api/history/getDocHistoryContent", model.CheckAuth, model.CheckAdminRole, getDocHistoryContent)
|
||||
ginServer.Handle("POST", "/api/history/rollbackDocHistory", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, rollbackDocHistory)
|
||||
ginServer.Handle("POST", "/api/history/clearWorkspaceHistory", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, clearWorkspaceHistory)
|
||||
ginServer.Handle("POST", "/api/history/reindexHistory", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, reindexHistory)
|
||||
ginServer.Handle("POST", "/api/history/searchHistory", model.CheckAuth, model.CheckAdminRole, searchHistory)
|
||||
ginServer.Handle("POST", "/api/history/getHistoryItems", model.CheckAuth, model.CheckAdminRole, getHistoryItems)
|
||||
|
||||
ginServer.Handle("POST", "/api/outline/getDocOutline", model.CheckAuth, getDocOutline)
|
||||
ginServer.Handle("POST", "/api/bookmark/getBookmark", model.CheckAuth, getBookmark)
|
||||
ginServer.Handle("POST", "/api/bookmark/renameBookmark", model.CheckAuth, model.CheckReadonly, renameBookmark)
|
||||
ginServer.Handle("POST", "/api/bookmark/removeBookmark", model.CheckAuth, model.CheckReadonly, removeBookmark)
|
||||
ginServer.Handle("POST", "/api/bookmark/renameBookmark", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, renameBookmark)
|
||||
ginServer.Handle("POST", "/api/bookmark/removeBookmark", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeBookmark)
|
||||
ginServer.Handle("POST", "/api/tag/getTag", model.CheckAuth, getTag)
|
||||
ginServer.Handle("POST", "/api/tag/renameTag", model.CheckAuth, model.CheckReadonly, renameTag)
|
||||
ginServer.Handle("POST", "/api/tag/removeTag", model.CheckAuth, model.CheckReadonly, removeTag)
|
||||
ginServer.Handle("POST", "/api/tag/renameTag", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, renameTag)
|
||||
ginServer.Handle("POST", "/api/tag/removeTag", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeTag)
|
||||
|
||||
ginServer.Handle("POST", "/api/lute/spinBlockDOM", model.CheckAuth, spinBlockDOM) // 未测试
|
||||
ginServer.Handle("POST", "/api/lute/html2BlockDOM", model.CheckAuth, html2BlockDOM)
|
||||
ginServer.Handle("POST", "/api/lute/copyStdMarkdown", model.CheckAuth, copyStdMarkdown)
|
||||
|
||||
ginServer.Handle("POST", "/api/query/sql", model.CheckAuth, SQL)
|
||||
ginServer.Handle("POST", "/api/sqlite/flushTransaction", model.CheckAuth, model.CheckReadonly, flushTransaction)
|
||||
ginServer.Handle("POST", "/api/sqlite/flushTransaction", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, flushTransaction)
|
||||
|
||||
ginServer.Handle("POST", "/api/search/searchTag", model.CheckAuth, searchTag)
|
||||
ginServer.Handle("POST", "/api/search/searchTemplate", model.CheckAuth, searchTemplate)
|
||||
ginServer.Handle("POST", "/api/search/removeTemplate", model.CheckAuth, model.CheckReadonly, removeTemplate)
|
||||
ginServer.Handle("POST", "/api/search/removeTemplate", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeTemplate)
|
||||
ginServer.Handle("POST", "/api/search/searchWidget", model.CheckAuth, searchWidget)
|
||||
ginServer.Handle("POST", "/api/search/searchRefBlock", model.CheckAuth, searchRefBlock)
|
||||
ginServer.Handle("POST", "/api/search/searchEmbedBlock", model.CheckAuth, searchEmbedBlock)
|
||||
|
@ -181,33 +180,33 @@ func ServeAPI(ginServer *gin.Engine) {
|
|||
ginServer.Handle("POST", "/api/block/getDocInfo", model.CheckAuth, getDocInfo)
|
||||
ginServer.Handle("POST", "/api/block/checkBlockExist", model.CheckAuth, checkBlockExist)
|
||||
ginServer.Handle("POST", "/api/block/checkBlockFold", model.CheckAuth, checkBlockFold)
|
||||
ginServer.Handle("POST", "/api/block/insertBlock", model.CheckAuth, model.CheckReadonly, insertBlock)
|
||||
ginServer.Handle("POST", "/api/block/prependBlock", model.CheckAuth, model.CheckReadonly, prependBlock)
|
||||
ginServer.Handle("POST", "/api/block/appendBlock", model.CheckAuth, model.CheckReadonly, appendBlock)
|
||||
ginServer.Handle("POST", "/api/block/appendDailyNoteBlock", model.CheckAuth, model.CheckReadonly, appendDailyNoteBlock)
|
||||
ginServer.Handle("POST", "/api/block/prependDailyNoteBlock", model.CheckAuth, model.CheckReadonly, prependDailyNoteBlock)
|
||||
ginServer.Handle("POST", "/api/block/updateBlock", model.CheckAuth, model.CheckReadonly, updateBlock)
|
||||
ginServer.Handle("POST", "/api/block/deleteBlock", model.CheckAuth, model.CheckReadonly, deleteBlock)
|
||||
ginServer.Handle("POST", "/api/block/moveBlock", model.CheckAuth, model.CheckReadonly, moveBlock)
|
||||
ginServer.Handle("POST", "/api/block/moveOutlineHeading", model.CheckAuth, model.CheckReadonly, moveOutlineHeading)
|
||||
ginServer.Handle("POST", "/api/block/foldBlock", model.CheckAuth, model.CheckReadonly, foldBlock)
|
||||
ginServer.Handle("POST", "/api/block/unfoldBlock", model.CheckAuth, model.CheckReadonly, unfoldBlock)
|
||||
ginServer.Handle("POST", "/api/block/setBlockReminder", model.CheckAuth, model.CheckReadonly, setBlockReminder)
|
||||
ginServer.Handle("POST", "/api/block/insertBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, insertBlock)
|
||||
ginServer.Handle("POST", "/api/block/prependBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, prependBlock)
|
||||
ginServer.Handle("POST", "/api/block/appendBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, appendBlock)
|
||||
ginServer.Handle("POST", "/api/block/appendDailyNoteBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, appendDailyNoteBlock)
|
||||
ginServer.Handle("POST", "/api/block/prependDailyNoteBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, prependDailyNoteBlock)
|
||||
ginServer.Handle("POST", "/api/block/updateBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, updateBlock)
|
||||
ginServer.Handle("POST", "/api/block/deleteBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, deleteBlock)
|
||||
ginServer.Handle("POST", "/api/block/moveBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, moveBlock)
|
||||
ginServer.Handle("POST", "/api/block/moveOutlineHeading", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, moveOutlineHeading)
|
||||
ginServer.Handle("POST", "/api/block/foldBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, foldBlock)
|
||||
ginServer.Handle("POST", "/api/block/unfoldBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, unfoldBlock)
|
||||
ginServer.Handle("POST", "/api/block/setBlockReminder", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setBlockReminder)
|
||||
ginServer.Handle("POST", "/api/block/getHeadingLevelTransaction", model.CheckAuth, getHeadingLevelTransaction)
|
||||
ginServer.Handle("POST", "/api/block/getHeadingDeleteTransaction", model.CheckAuth, getHeadingDeleteTransaction)
|
||||
ginServer.Handle("POST", "/api/block/getHeadingChildrenIDs", model.CheckAuth, getHeadingChildrenIDs)
|
||||
ginServer.Handle("POST", "/api/block/getHeadingChildrenDOM", model.CheckAuth, getHeadingChildrenDOM)
|
||||
ginServer.Handle("POST", "/api/block/swapBlockRef", model.CheckAuth, model.CheckReadonly, swapBlockRef)
|
||||
ginServer.Handle("POST", "/api/block/transferBlockRef", model.CheckAuth, model.CheckReadonly, transferBlockRef)
|
||||
ginServer.Handle("POST", "/api/block/swapBlockRef", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, swapBlockRef)
|
||||
ginServer.Handle("POST", "/api/block/transferBlockRef", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, transferBlockRef)
|
||||
ginServer.Handle("POST", "/api/block/getBlockSiblingID", model.CheckAuth, getBlockSiblingID)
|
||||
ginServer.Handle("POST", "/api/block/getBlockTreeInfos", model.CheckAuth, getBlockTreeInfos)
|
||||
|
||||
ginServer.Handle("POST", "/api/file/getFile", model.CheckAuth, getFile)
|
||||
ginServer.Handle("POST", "/api/file/putFile", model.CheckAuth, model.CheckReadonly, putFile)
|
||||
ginServer.Handle("POST", "/api/file/copyFile", model.CheckAuth, model.CheckReadonly, copyFile)
|
||||
ginServer.Handle("POST", "/api/file/globalCopyFiles", model.CheckAuth, model.CheckReadonly, globalCopyFiles)
|
||||
ginServer.Handle("POST", "/api/file/removeFile", model.CheckAuth, model.CheckReadonly, removeFile)
|
||||
ginServer.Handle("POST", "/api/file/renameFile", model.CheckAuth, model.CheckReadonly, renameFile)
|
||||
ginServer.Handle("POST", "/api/file/putFile", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, putFile)
|
||||
ginServer.Handle("POST", "/api/file/copyFile", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, copyFile)
|
||||
ginServer.Handle("POST", "/api/file/globalCopyFiles", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, globalCopyFiles)
|
||||
ginServer.Handle("POST", "/api/file/removeFile", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeFile)
|
||||
ginServer.Handle("POST", "/api/file/renameFile", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, renameFile)
|
||||
ginServer.Handle("POST", "/api/file/readDir", model.CheckAuth, readDir)
|
||||
ginServer.Handle("POST", "/api/file/getUniqueFilename", model.CheckAuth, getUniqueFilename)
|
||||
|
||||
|
@ -218,57 +217,57 @@ func ServeAPI(ginServer *gin.Engine) {
|
|||
ginServer.Handle("POST", "/api/ref/getBackmentionDoc", model.CheckAuth, getBackmentionDoc)
|
||||
|
||||
ginServer.Handle("POST", "/api/attr/getBookmarkLabels", model.CheckAuth, getBookmarkLabels)
|
||||
ginServer.Handle("POST", "/api/attr/resetBlockAttrs", model.CheckAuth, model.CheckReadonly, resetBlockAttrs)
|
||||
ginServer.Handle("POST", "/api/attr/setBlockAttrs", model.CheckAuth, model.CheckReadonly, setBlockAttrs)
|
||||
ginServer.Handle("POST", "/api/attr/batchSetBlockAttrs", model.CheckAuth, model.CheckReadonly, batchSetBlockAttrs)
|
||||
ginServer.Handle("POST", "/api/attr/resetBlockAttrs", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, resetBlockAttrs)
|
||||
ginServer.Handle("POST", "/api/attr/setBlockAttrs", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setBlockAttrs)
|
||||
ginServer.Handle("POST", "/api/attr/batchSetBlockAttrs", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, batchSetBlockAttrs)
|
||||
ginServer.Handle("POST", "/api/attr/getBlockAttrs", model.CheckAuth, getBlockAttrs)
|
||||
|
||||
ginServer.Handle("POST", "/api/cloud/getCloudSpace", model.CheckAuth, getCloudSpace)
|
||||
ginServer.Handle("POST", "/api/cloud/getCloudSpace", model.CheckAuth, model.CheckAdminRole, getCloudSpace)
|
||||
|
||||
ginServer.Handle("POST", "/api/sync/setSyncEnable", model.CheckAuth, model.CheckReadonly, setSyncEnable)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncPerception", model.CheckAuth, model.CheckReadonly, setSyncPerception)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncGenerateConflictDoc", model.CheckAuth, model.CheckReadonly, setSyncGenerateConflictDoc)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncMode", model.CheckAuth, model.CheckReadonly, setSyncMode)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncProvider", model.CheckAuth, model.CheckReadonly, setSyncProvider)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncProviderS3", model.CheckAuth, model.CheckReadonly, setSyncProviderS3)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncProviderWebDAV", model.CheckAuth, model.CheckReadonly, setSyncProviderWebDAV)
|
||||
ginServer.Handle("POST", "/api/sync/setCloudSyncDir", model.CheckAuth, model.CheckReadonly, setCloudSyncDir)
|
||||
ginServer.Handle("POST", "/api/sync/createCloudSyncDir", model.CheckAuth, model.CheckReadonly, createCloudSyncDir)
|
||||
ginServer.Handle("POST", "/api/sync/removeCloudSyncDir", model.CheckAuth, model.CheckReadonly, removeCloudSyncDir)
|
||||
ginServer.Handle("POST", "/api/sync/listCloudSyncDir", model.CheckAuth, listCloudSyncDir)
|
||||
ginServer.Handle("POST", "/api/sync/performSync", model.CheckAuth, model.CheckReadonly, performSync)
|
||||
ginServer.Handle("POST", "/api/sync/performBootSync", model.CheckAuth, model.CheckReadonly, performBootSync)
|
||||
ginServer.Handle("POST", "/api/sync/getBootSync", model.CheckAuth, getBootSync)
|
||||
ginServer.Handle("POST", "/api/sync/getSyncInfo", model.CheckAuth, getSyncInfo)
|
||||
ginServer.Handle("POST", "/api/sync/exportSyncProviderS3", model.CheckAuth, exportSyncProviderS3)
|
||||
ginServer.Handle("POST", "/api/sync/importSyncProviderS3", model.CheckAuth, model.CheckReadonly, importSyncProviderS3)
|
||||
ginServer.Handle("POST", "/api/sync/exportSyncProviderWebDAV", model.CheckAuth, exportSyncProviderWebDAV)
|
||||
ginServer.Handle("POST", "/api/sync/importSyncProviderWebDAV", model.CheckAuth, model.CheckReadonly, importSyncProviderWebDAV)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncEnable", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setSyncEnable)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncPerception", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setSyncPerception)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncGenerateConflictDoc", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setSyncGenerateConflictDoc)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncMode", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setSyncMode)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncProvider", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setSyncProvider)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncProviderS3", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setSyncProviderS3)
|
||||
ginServer.Handle("POST", "/api/sync/setSyncProviderWebDAV", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setSyncProviderWebDAV)
|
||||
ginServer.Handle("POST", "/api/sync/setCloudSyncDir", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setCloudSyncDir)
|
||||
ginServer.Handle("POST", "/api/sync/createCloudSyncDir", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, createCloudSyncDir)
|
||||
ginServer.Handle("POST", "/api/sync/removeCloudSyncDir", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeCloudSyncDir)
|
||||
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, 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)
|
||||
ginServer.Handle("POST", "/api/sync/exportSyncProviderWebDAV", model.CheckAuth, model.CheckAdminRole, exportSyncProviderWebDAV)
|
||||
ginServer.Handle("POST", "/api/sync/importSyncProviderWebDAV", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importSyncProviderWebDAV)
|
||||
|
||||
ginServer.Handle("POST", "/api/inbox/getShorthands", model.CheckAuth, getShorthands)
|
||||
ginServer.Handle("POST", "/api/inbox/getShorthand", model.CheckAuth, getShorthand)
|
||||
ginServer.Handle("POST", "/api/inbox/removeShorthands", model.CheckAuth, model.CheckReadonly, removeShorthands)
|
||||
ginServer.Handle("POST", "/api/inbox/getShorthands", model.CheckAuth, model.CheckAdminRole, getShorthands)
|
||||
ginServer.Handle("POST", "/api/inbox/getShorthand", model.CheckAuth, model.CheckAdminRole, getShorthand)
|
||||
ginServer.Handle("POST", "/api/inbox/removeShorthands", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeShorthands)
|
||||
|
||||
ginServer.Handle("POST", "/api/extension/copy", model.CheckAuth, model.CheckReadonly, extensionCopy)
|
||||
ginServer.Handle("POST", "/api/extension/copy", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, extensionCopy)
|
||||
|
||||
ginServer.Handle("POST", "/api/clipboard/readFilePaths", model.CheckAuth, readFilePaths)
|
||||
ginServer.Handle("POST", "/api/clipboard/readFilePaths", model.CheckAuth, model.CheckAdminRole, readFilePaths)
|
||||
|
||||
ginServer.Handle("POST", "/api/asset/uploadCloud", model.CheckAuth, model.CheckReadonly, uploadCloud)
|
||||
ginServer.Handle("POST", "/api/asset/insertLocalAssets", model.CheckAuth, model.CheckReadonly, insertLocalAssets)
|
||||
ginServer.Handle("POST", "/api/asset/uploadCloud", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, uploadCloud)
|
||||
ginServer.Handle("POST", "/api/asset/insertLocalAssets", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, insertLocalAssets)
|
||||
ginServer.Handle("POST", "/api/asset/resolveAssetPath", model.CheckAuth, resolveAssetPath)
|
||||
ginServer.Handle("POST", "/api/asset/upload", model.CheckAuth, model.CheckReadonly, model.Upload)
|
||||
ginServer.Handle("POST", "/api/asset/setFileAnnotation", model.CheckAuth, model.CheckReadonly, setFileAnnotation)
|
||||
ginServer.Handle("POST", "/api/asset/upload", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, model.Upload)
|
||||
ginServer.Handle("POST", "/api/asset/setFileAnnotation", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setFileAnnotation)
|
||||
ginServer.Handle("POST", "/api/asset/getFileAnnotation", model.CheckAuth, getFileAnnotation)
|
||||
ginServer.Handle("POST", "/api/asset/getUnusedAssets", model.CheckAuth, getUnusedAssets)
|
||||
ginServer.Handle("POST", "/api/asset/getMissingAssets", model.CheckAuth, getMissingAssets)
|
||||
ginServer.Handle("POST", "/api/asset/removeUnusedAsset", model.CheckAuth, model.CheckReadonly, removeUnusedAsset)
|
||||
ginServer.Handle("POST", "/api/asset/removeUnusedAssets", model.CheckAuth, model.CheckReadonly, removeUnusedAssets)
|
||||
ginServer.Handle("POST", "/api/asset/removeUnusedAsset", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeUnusedAsset)
|
||||
ginServer.Handle("POST", "/api/asset/removeUnusedAssets", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeUnusedAssets)
|
||||
ginServer.Handle("POST", "/api/asset/getDocImageAssets", model.CheckAuth, getDocImageAssets)
|
||||
ginServer.Handle("POST", "/api/asset/renameAsset", model.CheckAuth, model.CheckReadonly, renameAsset)
|
||||
ginServer.Handle("POST", "/api/asset/getImageOCRText", model.CheckAuth, model.CheckReadonly, getImageOCRText)
|
||||
ginServer.Handle("POST", "/api/asset/setImageOCRText", model.CheckAuth, model.CheckReadonly, setImageOCRText)
|
||||
ginServer.Handle("POST", "/api/asset/fullReindexAssetContent", model.CheckAuth, model.CheckReadonly, fullReindexAssetContent)
|
||||
ginServer.Handle("POST", "/api/asset/statAsset", model.CheckAuth, statAsset)
|
||||
ginServer.Handle("POST", "/api/asset/renameAsset", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, renameAsset)
|
||||
ginServer.Handle("POST", "/api/asset/getImageOCRText", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, getImageOCRText)
|
||||
ginServer.Handle("POST", "/api/asset/setImageOCRText", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setImageOCRText)
|
||||
ginServer.Handle("POST", "/api/asset/fullReindexAssetContent", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, fullReindexAssetContent)
|
||||
ginServer.Handle("POST", "/api/asset/statAsset", model.CheckAuth, model.CheckAdminRole, statAsset)
|
||||
|
||||
ginServer.Handle("POST", "/api/export/batchExportMd", model.CheckAuth, batchExportMd)
|
||||
ginServer.Handle("POST", "/api/export/exportMd", model.CheckAuth, exportMd)
|
||||
|
@ -286,7 +285,7 @@ func ServeAPI(ginServer *gin.Engine) {
|
|||
ginServer.Handle("POST", "/api/export/exportData", model.CheckAuth, exportData)
|
||||
ginServer.Handle("POST", "/api/export/exportDataInFolder", model.CheckAuth, exportDataInFolder)
|
||||
ginServer.Handle("POST", "/api/export/exportTempContent", model.CheckAuth, exportTempContent)
|
||||
ginServer.Handle("POST", "/api/export/export2Liandi", model.CheckAuth, export2Liandi)
|
||||
ginServer.Handle("POST", "/api/export/export2Liandi", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, export2Liandi)
|
||||
ginServer.Handle("POST", "/api/export/exportReStructuredText", model.CheckAuth, exportReStructuredText)
|
||||
ginServer.Handle("POST", "/api/export/exportAsciiDoc", model.CheckAuth, exportAsciiDoc)
|
||||
ginServer.Handle("POST", "/api/export/exportTextile", model.CheckAuth, exportTextile)
|
||||
|
@ -298,150 +297,152 @@ func ServeAPI(ginServer *gin.Engine) {
|
|||
ginServer.Handle("POST", "/api/export/exportEPUB", model.CheckAuth, exportEPUB)
|
||||
ginServer.Handle("POST", "/api/export/exportAttributeView", model.CheckAuth, exportAttributeView)
|
||||
|
||||
ginServer.Handle("POST", "/api/import/importStdMd", model.CheckAuth, model.CheckReadonly, importStdMd)
|
||||
ginServer.Handle("POST", "/api/import/importData", model.CheckAuth, model.CheckReadonly, importData)
|
||||
ginServer.Handle("POST", "/api/import/importSY", model.CheckAuth, model.CheckReadonly, importSY)
|
||||
ginServer.Handle("POST", "/api/import/importStdMd", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importStdMd)
|
||||
ginServer.Handle("POST", "/api/import/importData", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importData)
|
||||
ginServer.Handle("POST", "/api/import/importSY", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importSY)
|
||||
|
||||
ginServer.Handle("POST", "/api/convert/pandoc", model.CheckAuth, model.CheckReadonly, pandoc)
|
||||
ginServer.Handle("POST", "/api/convert/pandoc", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, pandoc)
|
||||
|
||||
ginServer.Handle("POST", "/api/template/render", model.CheckAuth, renderTemplate)
|
||||
ginServer.Handle("POST", "/api/template/docSaveAsTemplate", model.CheckAuth, model.CheckReadonly, docSaveAsTemplate)
|
||||
ginServer.Handle("POST", "/api/template/render", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, renderTemplate)
|
||||
ginServer.Handle("POST", "/api/template/docSaveAsTemplate", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, docSaveAsTemplate)
|
||||
ginServer.Handle("POST", "/api/template/renderSprig", model.CheckAuth, renderSprig)
|
||||
|
||||
ginServer.Handle("POST", "/api/transactions", model.CheckAuth, model.CheckReadonly, performTransactions)
|
||||
ginServer.Handle("POST", "/api/transactions", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, performTransactions)
|
||||
|
||||
ginServer.Handle("POST", "/api/setting/setAccount", model.CheckAuth, model.CheckReadonly, setAccount)
|
||||
ginServer.Handle("POST", "/api/setting/setEditor", model.CheckAuth, model.CheckReadonly, setEditor)
|
||||
ginServer.Handle("POST", "/api/setting/setExport", model.CheckAuth, model.CheckReadonly, setExport)
|
||||
ginServer.Handle("POST", "/api/setting/setFiletree", model.CheckAuth, model.CheckReadonly, setFiletree)
|
||||
ginServer.Handle("POST", "/api/setting/setSearch", model.CheckAuth, model.CheckReadonly, setSearch)
|
||||
ginServer.Handle("POST", "/api/setting/setKeymap", model.CheckAuth, model.CheckReadonly, setKeymap)
|
||||
ginServer.Handle("POST", "/api/setting/setAppearance", model.CheckAuth, model.CheckReadonly, setAppearance)
|
||||
ginServer.Handle("POST", "/api/setting/getCloudUser", model.CheckAuth, getCloudUser)
|
||||
ginServer.Handle("POST", "/api/setting/logoutCloudUser", model.CheckAuth, model.CheckReadonly, logoutCloudUser)
|
||||
ginServer.Handle("POST", "/api/setting/login2faCloudUser", model.CheckAuth, model.CheckReadonly, login2faCloudUser)
|
||||
ginServer.Handle("POST", "/api/setting/setEmoji", model.CheckAuth, model.CheckReadonly, setEmoji)
|
||||
ginServer.Handle("POST", "/api/setting/setFlashcard", model.CheckAuth, model.CheckReadonly, setFlashcard)
|
||||
ginServer.Handle("POST", "/api/setting/setAI", model.CheckAuth, model.CheckReadonly, setAI)
|
||||
ginServer.Handle("POST", "/api/setting/setBazaar", model.CheckAuth, model.CheckReadonly, setBazaar)
|
||||
ginServer.Handle("POST", "/api/setting/refreshVirtualBlockRef", model.CheckAuth, model.CheckReadonly, refreshVirtualBlockRef)
|
||||
ginServer.Handle("POST", "/api/setting/addVirtualBlockRefInclude", model.CheckAuth, model.CheckReadonly, addVirtualBlockRefInclude)
|
||||
ginServer.Handle("POST", "/api/setting/addVirtualBlockRefExclude", model.CheckAuth, model.CheckReadonly, addVirtualBlockRefExclude)
|
||||
ginServer.Handle("POST", "/api/setting/setSnippet", model.CheckAuth, model.CheckReadonly, setConfSnippet)
|
||||
ginServer.Handle("POST", "/api/setting/setEditorReadOnly", model.CheckAuth, model.CheckReadonly, setEditorReadOnly)
|
||||
ginServer.Handle("POST", "/api/setting/setAccount", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setAccount)
|
||||
ginServer.Handle("POST", "/api/setting/setEditor", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setEditor)
|
||||
ginServer.Handle("POST", "/api/setting/setExport", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setExport)
|
||||
ginServer.Handle("POST", "/api/setting/setFiletree", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setFiletree)
|
||||
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, 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)
|
||||
ginServer.Handle("POST", "/api/setting/setFlashcard", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setFlashcard)
|
||||
ginServer.Handle("POST", "/api/setting/setAI", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setAI)
|
||||
ginServer.Handle("POST", "/api/setting/setBazaar", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setBazaar)
|
||||
ginServer.Handle("POST", "/api/setting/setPublish", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setPublish)
|
||||
ginServer.Handle("POST", "/api/setting/getPublish", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, getPublish)
|
||||
ginServer.Handle("POST", "/api/setting/refreshVirtualBlockRef", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, refreshVirtualBlockRef)
|
||||
ginServer.Handle("POST", "/api/setting/addVirtualBlockRefInclude", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, addVirtualBlockRefInclude)
|
||||
ginServer.Handle("POST", "/api/setting/addVirtualBlockRefExclude", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, addVirtualBlockRefExclude)
|
||||
ginServer.Handle("POST", "/api/setting/setSnippet", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setConfSnippet)
|
||||
ginServer.Handle("POST", "/api/setting/setEditorReadOnly", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setEditorReadOnly)
|
||||
|
||||
ginServer.Handle("POST", "/api/graph/resetGraph", model.CheckAuth, model.CheckReadonly, resetGraph)
|
||||
ginServer.Handle("POST", "/api/graph/resetLocalGraph", model.CheckAuth, model.CheckReadonly, resetLocalGraph)
|
||||
ginServer.Handle("POST", "/api/graph/resetGraph", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, resetGraph)
|
||||
ginServer.Handle("POST", "/api/graph/resetLocalGraph", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, resetLocalGraph)
|
||||
ginServer.Handle("POST", "/api/graph/getGraph", model.CheckAuth, getGraph)
|
||||
ginServer.Handle("POST", "/api/graph/getLocalGraph", model.CheckAuth, getLocalGraph)
|
||||
|
||||
ginServer.Handle("POST", "/api/bazaar/getBazaarPlugin", model.CheckAuth, getBazaarPlugin)
|
||||
ginServer.Handle("POST", "/api/bazaar/getInstalledPlugin", model.CheckAuth, getInstalledPlugin)
|
||||
ginServer.Handle("POST", "/api/bazaar/installBazaarPlugin", model.CheckAuth, model.CheckReadonly, installBazaarPlugin)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarPlugin", model.CheckAuth, model.CheckReadonly, uninstallBazaarPlugin)
|
||||
ginServer.Handle("POST", "/api/bazaar/installBazaarPlugin", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, installBazaarPlugin)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarPlugin", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, uninstallBazaarPlugin)
|
||||
ginServer.Handle("POST", "/api/bazaar/getBazaarWidget", model.CheckAuth, getBazaarWidget)
|
||||
ginServer.Handle("POST", "/api/bazaar/getInstalledWidget", model.CheckAuth, getInstalledWidget)
|
||||
ginServer.Handle("POST", "/api/bazaar/installBazaarWidget", model.CheckAuth, model.CheckReadonly, installBazaarWidget)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarWidget", model.CheckAuth, model.CheckReadonly, uninstallBazaarWidget)
|
||||
ginServer.Handle("POST", "/api/bazaar/installBazaarWidget", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, installBazaarWidget)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarWidget", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, uninstallBazaarWidget)
|
||||
ginServer.Handle("POST", "/api/bazaar/getBazaarIcon", model.CheckAuth, getBazaarIcon)
|
||||
ginServer.Handle("POST", "/api/bazaar/getInstalledIcon", model.CheckAuth, getInstalledIcon)
|
||||
ginServer.Handle("POST", "/api/bazaar/installBazaarIcon", model.CheckAuth, model.CheckReadonly, installBazaarIcon)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarIcon", model.CheckAuth, model.CheckReadonly, uninstallBazaarIcon)
|
||||
ginServer.Handle("POST", "/api/bazaar/installBazaarIcon", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, installBazaarIcon)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarIcon", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, uninstallBazaarIcon)
|
||||
ginServer.Handle("POST", "/api/bazaar/getBazaarTemplate", model.CheckAuth, getBazaarTemplate)
|
||||
ginServer.Handle("POST", "/api/bazaar/getInstalledTemplate", model.CheckAuth, getInstalledTemplate)
|
||||
ginServer.Handle("POST", "/api/bazaar/installBazaarTemplate", model.CheckAuth, model.CheckReadonly, installBazaarTemplate)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarTemplate", model.CheckAuth, model.CheckReadonly, uninstallBazaarTemplate)
|
||||
ginServer.Handle("POST", "/api/bazaar/installBazaarTemplate", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, installBazaarTemplate)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarTemplate", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, uninstallBazaarTemplate)
|
||||
ginServer.Handle("POST", "/api/bazaar/getBazaarTheme", model.CheckAuth, getBazaarTheme)
|
||||
ginServer.Handle("POST", "/api/bazaar/getInstalledTheme", model.CheckAuth, getInstalledTheme)
|
||||
ginServer.Handle("POST", "/api/bazaar/installBazaarTheme", model.CheckAuth, model.CheckReadonly, installBazaarTheme)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarTheme", model.CheckAuth, model.CheckReadonly, uninstallBazaarTheme)
|
||||
ginServer.Handle("POST", "/api/bazaar/installBazaarTheme", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, installBazaarTheme)
|
||||
ginServer.Handle("POST", "/api/bazaar/uninstallBazaarTheme", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, uninstallBazaarTheme)
|
||||
ginServer.Handle("POST", "/api/bazaar/getBazaarPackageREAME", model.CheckAuth, getBazaarPackageREAME)
|
||||
ginServer.Handle("POST", "/api/bazaar/getUpdatedPackage", model.CheckAuth, getUpdatedPackage)
|
||||
ginServer.Handle("POST", "/api/bazaar/batchUpdatePackage", model.CheckAuth, batchUpdatePackage)
|
||||
ginServer.Handle("POST", "/api/bazaar/batchUpdatePackage", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, batchUpdatePackage)
|
||||
|
||||
ginServer.Handle("POST", "/api/repo/initRepoKey", model.CheckAuth, model.CheckReadonly, initRepoKey)
|
||||
ginServer.Handle("POST", "/api/repo/initRepoKeyFromPassphrase", model.CheckAuth, model.CheckReadonly, initRepoKeyFromPassphrase)
|
||||
ginServer.Handle("POST", "/api/repo/resetRepo", model.CheckAuth, model.CheckReadonly, resetRepo)
|
||||
ginServer.Handle("POST", "/api/repo/purgeRepo", model.CheckAuth, model.CheckReadonly, purgeRepo)
|
||||
ginServer.Handle("POST", "/api/repo/purgeCloudRepo", model.CheckAuth, model.CheckReadonly, purgeCloudRepo)
|
||||
ginServer.Handle("POST", "/api/repo/importRepoKey", model.CheckAuth, model.CheckReadonly, importRepoKey)
|
||||
ginServer.Handle("POST", "/api/repo/createSnapshot", model.CheckAuth, model.CheckReadonly, createSnapshot)
|
||||
ginServer.Handle("POST", "/api/repo/tagSnapshot", model.CheckAuth, model.CheckReadonly, tagSnapshot)
|
||||
ginServer.Handle("POST", "/api/repo/checkoutRepo", model.CheckAuth, model.CheckReadonly, checkoutRepo)
|
||||
ginServer.Handle("POST", "/api/repo/getRepoSnapshots", model.CheckAuth, getRepoSnapshots)
|
||||
ginServer.Handle("POST", "/api/repo/getRepoTagSnapshots", model.CheckAuth, getRepoTagSnapshots)
|
||||
ginServer.Handle("POST", "/api/repo/removeRepoTagSnapshot", model.CheckAuth, model.CheckReadonly, removeRepoTagSnapshot)
|
||||
ginServer.Handle("POST", "/api/repo/getCloudRepoTagSnapshots", model.CheckAuth, getCloudRepoTagSnapshots)
|
||||
ginServer.Handle("POST", "/api/repo/getCloudRepoSnapshots", model.CheckAuth, getCloudRepoSnapshots)
|
||||
ginServer.Handle("POST", "/api/repo/removeCloudRepoTagSnapshot", model.CheckAuth, model.CheckReadonly, removeCloudRepoTagSnapshot)
|
||||
ginServer.Handle("POST", "/api/repo/uploadCloudSnapshot", model.CheckAuth, model.CheckReadonly, uploadCloudSnapshot)
|
||||
ginServer.Handle("POST", "/api/repo/downloadCloudSnapshot", model.CheckAuth, model.CheckReadonly, downloadCloudSnapshot)
|
||||
ginServer.Handle("POST", "/api/repo/diffRepoSnapshots", model.CheckAuth, diffRepoSnapshots)
|
||||
ginServer.Handle("POST", "/api/repo/openRepoSnapshotDoc", model.CheckAuth, openRepoSnapshotDoc)
|
||||
ginServer.Handle("POST", "/api/repo/getRepoFile", model.CheckAuth, getRepoFile)
|
||||
ginServer.Handle("POST", "/api/repo/initRepoKey", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, initRepoKey)
|
||||
ginServer.Handle("POST", "/api/repo/initRepoKeyFromPassphrase", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, initRepoKeyFromPassphrase)
|
||||
ginServer.Handle("POST", "/api/repo/resetRepo", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, resetRepo)
|
||||
ginServer.Handle("POST", "/api/repo/purgeRepo", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, purgeRepo)
|
||||
ginServer.Handle("POST", "/api/repo/purgeCloudRepo", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, purgeCloudRepo)
|
||||
ginServer.Handle("POST", "/api/repo/importRepoKey", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importRepoKey)
|
||||
ginServer.Handle("POST", "/api/repo/createSnapshot", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, createSnapshot)
|
||||
ginServer.Handle("POST", "/api/repo/tagSnapshot", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, tagSnapshot)
|
||||
ginServer.Handle("POST", "/api/repo/checkoutRepo", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, checkoutRepo)
|
||||
ginServer.Handle("POST", "/api/repo/getRepoSnapshots", model.CheckAuth, model.CheckAdminRole, getRepoSnapshots)
|
||||
ginServer.Handle("POST", "/api/repo/getRepoTagSnapshots", model.CheckAuth, model.CheckAdminRole, getRepoTagSnapshots)
|
||||
ginServer.Handle("POST", "/api/repo/removeRepoTagSnapshot", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeRepoTagSnapshot)
|
||||
ginServer.Handle("POST", "/api/repo/getCloudRepoTagSnapshots", model.CheckAuth, model.CheckAdminRole, getCloudRepoTagSnapshots)
|
||||
ginServer.Handle("POST", "/api/repo/getCloudRepoSnapshots", model.CheckAuth, model.CheckAdminRole, getCloudRepoSnapshots)
|
||||
ginServer.Handle("POST", "/api/repo/removeCloudRepoTagSnapshot", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeCloudRepoTagSnapshot)
|
||||
ginServer.Handle("POST", "/api/repo/uploadCloudSnapshot", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, uploadCloudSnapshot)
|
||||
ginServer.Handle("POST", "/api/repo/downloadCloudSnapshot", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, downloadCloudSnapshot)
|
||||
ginServer.Handle("POST", "/api/repo/diffRepoSnapshots", model.CheckAuth, model.CheckAdminRole, diffRepoSnapshots)
|
||||
ginServer.Handle("POST", "/api/repo/openRepoSnapshotDoc", model.CheckAuth, model.CheckAdminRole, openRepoSnapshotDoc)
|
||||
ginServer.Handle("POST", "/api/repo/getRepoFile", model.CheckAuth, model.CheckAdminRole, getRepoFile)
|
||||
|
||||
ginServer.Handle("POST", "/api/riff/createRiffDeck", model.CheckAuth, model.CheckReadonly, createRiffDeck)
|
||||
ginServer.Handle("POST", "/api/riff/renameRiffDeck", model.CheckAuth, model.CheckReadonly, renameRiffDeck)
|
||||
ginServer.Handle("POST", "/api/riff/removeRiffDeck", model.CheckAuth, model.CheckReadonly, removeRiffDeck)
|
||||
ginServer.Handle("POST", "/api/riff/getRiffDecks", model.CheckAuth, getRiffDecks)
|
||||
ginServer.Handle("POST", "/api/riff/addRiffCards", model.CheckAuth, model.CheckReadonly, addRiffCards)
|
||||
ginServer.Handle("POST", "/api/riff/removeRiffCards", model.CheckAuth, model.CheckReadonly, removeRiffCards)
|
||||
ginServer.Handle("POST", "/api/riff/getRiffDueCards", model.CheckAuth, getRiffDueCards)
|
||||
ginServer.Handle("POST", "/api/riff/getTreeRiffDueCards", model.CheckAuth, getTreeRiffDueCards)
|
||||
ginServer.Handle("POST", "/api/riff/getNotebookRiffDueCards", model.CheckAuth, getNotebookRiffDueCards)
|
||||
ginServer.Handle("POST", "/api/riff/reviewRiffCard", model.CheckAuth, model.CheckReadonly, reviewRiffCard)
|
||||
ginServer.Handle("POST", "/api/riff/skipReviewRiffCard", model.CheckAuth, model.CheckReadonly, skipReviewRiffCard)
|
||||
ginServer.Handle("POST", "/api/riff/getRiffCards", model.CheckAuth, getRiffCards)
|
||||
ginServer.Handle("POST", "/api/riff/getTreeRiffCards", model.CheckAuth, getTreeRiffCards)
|
||||
ginServer.Handle("POST", "/api/riff/getNotebookRiffCards", model.CheckAuth, getNotebookRiffCards)
|
||||
ginServer.Handle("POST", "/api/riff/resetRiffCards", model.CheckAuth, model.CheckReadonly, resetRiffCards)
|
||||
ginServer.Handle("POST", "/api/riff/batchSetRiffCardsDueTime", model.CheckAuth, model.CheckReadonly, batchSetRiffCardsDueTime)
|
||||
ginServer.Handle("POST", "/api/riff/getRiffCardsByBlockIDs", model.CheckAuth, model.CheckReadonly, getRiffCardsByBlockIDs)
|
||||
ginServer.Handle("POST", "/api/riff/createRiffDeck", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, createRiffDeck)
|
||||
ginServer.Handle("POST", "/api/riff/renameRiffDeck", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, renameRiffDeck)
|
||||
ginServer.Handle("POST", "/api/riff/removeRiffDeck", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeRiffDeck)
|
||||
ginServer.Handle("POST", "/api/riff/getRiffDecks", model.CheckAuth, model.CheckAdminRole, getRiffDecks)
|
||||
ginServer.Handle("POST", "/api/riff/addRiffCards", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, addRiffCards)
|
||||
ginServer.Handle("POST", "/api/riff/removeRiffCards", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeRiffCards)
|
||||
ginServer.Handle("POST", "/api/riff/getRiffDueCards", model.CheckAuth, model.CheckAdminRole, getRiffDueCards)
|
||||
ginServer.Handle("POST", "/api/riff/getTreeRiffDueCards", model.CheckAuth, model.CheckAdminRole, getTreeRiffDueCards)
|
||||
ginServer.Handle("POST", "/api/riff/getNotebookRiffDueCards", model.CheckAuth, model.CheckAdminRole, getNotebookRiffDueCards)
|
||||
ginServer.Handle("POST", "/api/riff/reviewRiffCard", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, reviewRiffCard)
|
||||
ginServer.Handle("POST", "/api/riff/skipReviewRiffCard", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, skipReviewRiffCard)
|
||||
ginServer.Handle("POST", "/api/riff/getRiffCards", model.CheckAuth, model.CheckAdminRole, getRiffCards)
|
||||
ginServer.Handle("POST", "/api/riff/getTreeRiffCards", model.CheckAuth, model.CheckAdminRole, getTreeRiffCards)
|
||||
ginServer.Handle("POST", "/api/riff/getNotebookRiffCards", model.CheckAuth, model.CheckAdminRole, getNotebookRiffCards)
|
||||
ginServer.Handle("POST", "/api/riff/resetRiffCards", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, resetRiffCards)
|
||||
ginServer.Handle("POST", "/api/riff/batchSetRiffCardsDueTime", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, batchSetRiffCardsDueTime)
|
||||
ginServer.Handle("POST", "/api/riff/getRiffCardsByBlockIDs", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, getRiffCardsByBlockIDs)
|
||||
|
||||
ginServer.Handle("POST", "/api/notification/pushMsg", model.CheckAuth, pushMsg)
|
||||
ginServer.Handle("POST", "/api/notification/pushErrMsg", model.CheckAuth, pushErrMsg)
|
||||
ginServer.Handle("POST", "/api/notification/pushMsg", model.CheckAuth, model.CheckAdminRole, pushMsg)
|
||||
ginServer.Handle("POST", "/api/notification/pushErrMsg", model.CheckAuth, model.CheckAdminRole, pushErrMsg)
|
||||
|
||||
ginServer.Handle("POST", "/api/snippet/getSnippet", model.CheckAuth, getSnippet)
|
||||
ginServer.Handle("POST", "/api/snippet/setSnippet", model.CheckAuth, model.CheckReadonly, setSnippet)
|
||||
ginServer.Handle("POST", "/api/snippet/removeSnippet", model.CheckAuth, model.CheckReadonly, removeSnippet)
|
||||
ginServer.Handle("POST", "/api/snippet/setSnippet", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setSnippet)
|
||||
ginServer.Handle("POST", "/api/snippet/removeSnippet", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeSnippet)
|
||||
|
||||
ginServer.Handle("POST", "/api/av/renderAttributeView", model.CheckAuth, renderAttributeView)
|
||||
ginServer.Handle("POST", "/api/av/renderHistoryAttributeView", model.CheckAuth, renderHistoryAttributeView)
|
||||
ginServer.Handle("POST", "/api/av/renderSnapshotAttributeView", model.CheckAuth, renderSnapshotAttributeView)
|
||||
ginServer.Handle("POST", "/api/av/renderHistoryAttributeView", model.CheckAuth, model.CheckAdminRole, renderHistoryAttributeView)
|
||||
ginServer.Handle("POST", "/api/av/renderSnapshotAttributeView", model.CheckAuth, model.CheckAdminRole, renderSnapshotAttributeView)
|
||||
ginServer.Handle("POST", "/api/av/getAttributeViewKeys", model.CheckAuth, getAttributeViewKeys)
|
||||
ginServer.Handle("POST", "/api/av/setAttributeViewBlockAttr", model.CheckAuth, model.CheckReadonly, setAttributeViewBlockAttr)
|
||||
ginServer.Handle("POST", "/api/av/setAttributeViewBlockAttr", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setAttributeViewBlockAttr)
|
||||
ginServer.Handle("POST", "/api/av/searchAttributeView", model.CheckAuth, model.CheckReadonly, searchAttributeView)
|
||||
ginServer.Handle("POST", "/api/av/getAttributeView", model.CheckAuth, model.CheckReadonly, getAttributeView)
|
||||
ginServer.Handle("POST", "/api/av/searchAttributeViewRelationKey", model.CheckAuth, model.CheckReadonly, searchAttributeViewRelationKey)
|
||||
ginServer.Handle("POST", "/api/av/searchAttributeViewNonRelationKey", model.CheckAuth, model.CheckReadonly, searchAttributeViewNonRelationKey)
|
||||
ginServer.Handle("POST", "/api/av/getAttributeViewFilterSort", model.CheckAuth, model.CheckReadonly, getAttributeViewFilterSort)
|
||||
ginServer.Handle("POST", "/api/av/addAttributeViewKey", model.CheckAuth, model.CheckReadonly, addAttributeViewKey)
|
||||
ginServer.Handle("POST", "/api/av/removeAttributeViewKey", model.CheckAuth, model.CheckReadonly, removeAttributeViewKey)
|
||||
ginServer.Handle("POST", "/api/av/sortAttributeViewViewKey", model.CheckAuth, model.CheckReadonly, sortAttributeViewViewKey)
|
||||
ginServer.Handle("POST", "/api/av/sortAttributeViewKey", model.CheckAuth, model.CheckReadonly, sortAttributeViewKey)
|
||||
ginServer.Handle("POST", "/api/av/addAttributeViewBlocks", model.CheckAuth, model.CheckReadonly, addAttributeViewBlocks)
|
||||
ginServer.Handle("POST", "/api/av/removeAttributeViewBlocks", model.CheckAuth, model.CheckReadonly, removeAttributeViewBlocks)
|
||||
ginServer.Handle("POST", "/api/av/getAttributeViewPrimaryKeyValues", model.CheckAuth, model.CheckReadonly, getAttributeViewPrimaryKeyValues)
|
||||
ginServer.Handle("POST", "/api/av/setDatabaseBlockView", model.CheckAuth, model.CheckReadonly, setDatabaseBlockView)
|
||||
ginServer.Handle("POST", "/api/av/getMirrorDatabaseBlocks", model.CheckAuth, model.CheckReadonly, getMirrorDatabaseBlocks)
|
||||
ginServer.Handle("POST", "/api/av/getAttributeViewKeysByAvID", model.CheckAuth, model.CheckReadonly, getAttributeViewKeysByAvID)
|
||||
ginServer.Handle("POST", "/api/av/duplicateAttributeViewBlock", model.CheckAuth, model.CheckReadonly, duplicateAttributeViewBlock)
|
||||
ginServer.Handle("POST", "/api/av/appendAttributeViewDetachedBlocksWithValues", model.CheckAuth, model.CheckReadonly, appendAttributeViewDetachedBlocksWithValues)
|
||||
ginServer.Handle("POST", "/api/av/searchAttributeViewRelationKey", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, searchAttributeViewRelationKey)
|
||||
ginServer.Handle("POST", "/api/av/searchAttributeViewNonRelationKey", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, searchAttributeViewNonRelationKey)
|
||||
ginServer.Handle("POST", "/api/av/getAttributeViewFilterSort", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, getAttributeViewFilterSort)
|
||||
ginServer.Handle("POST", "/api/av/addAttributeViewKey", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, addAttributeViewKey)
|
||||
ginServer.Handle("POST", "/api/av/removeAttributeViewKey", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeAttributeViewKey)
|
||||
ginServer.Handle("POST", "/api/av/sortAttributeViewViewKey", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, sortAttributeViewViewKey)
|
||||
ginServer.Handle("POST", "/api/av/sortAttributeViewKey", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, sortAttributeViewKey)
|
||||
ginServer.Handle("POST", "/api/av/addAttributeViewBlocks", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, addAttributeViewBlocks)
|
||||
ginServer.Handle("POST", "/api/av/removeAttributeViewBlocks", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeAttributeViewBlocks)
|
||||
ginServer.Handle("POST", "/api/av/getAttributeViewPrimaryKeyValues", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, getAttributeViewPrimaryKeyValues)
|
||||
ginServer.Handle("POST", "/api/av/setDatabaseBlockView", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setDatabaseBlockView)
|
||||
ginServer.Handle("POST", "/api/av/getMirrorDatabaseBlocks", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, getMirrorDatabaseBlocks)
|
||||
ginServer.Handle("POST", "/api/av/getAttributeViewKeysByAvID", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, getAttributeViewKeysByAvID)
|
||||
ginServer.Handle("POST", "/api/av/duplicateAttributeViewBlock", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, duplicateAttributeViewBlock)
|
||||
ginServer.Handle("POST", "/api/av/appendAttributeViewDetachedBlocksWithValues", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, appendAttributeViewDetachedBlocksWithValues)
|
||||
|
||||
ginServer.Handle("POST", "/api/ai/chatGPT", model.CheckAuth, chatGPT)
|
||||
ginServer.Handle("POST", "/api/ai/chatGPTWithAction", model.CheckAuth, chatGPTWithAction)
|
||||
ginServer.Handle("POST", "/api/ai/chatGPT", model.CheckAuth, model.CheckAdminRole, chatGPT)
|
||||
ginServer.Handle("POST", "/api/ai/chatGPTWithAction", model.CheckAuth, model.CheckAdminRole, chatGPTWithAction)
|
||||
|
||||
ginServer.Handle("POST", "/api/petal/loadPetals", model.CheckAuth, loadPetals)
|
||||
ginServer.Handle("POST", "/api/petal/setPetalEnabled", model.CheckAuth, model.CheckReadonly, setPetalEnabled)
|
||||
ginServer.Handle("POST", "/api/petal/setPetalEnabled", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setPetalEnabled)
|
||||
|
||||
ginServer.Any("/api/network/echo", model.CheckAuth, echo)
|
||||
ginServer.Handle("POST", "/api/network/forwardProxy", model.CheckAuth, forwardProxy)
|
||||
ginServer.Any("/api/network/echo", model.CheckAuth, model.CheckAdminRole, echo)
|
||||
ginServer.Handle("POST", "/api/network/forwardProxy", model.CheckAuth, model.CheckAdminRole, forwardProxy)
|
||||
|
||||
ginServer.Handle("GET", "/ws/broadcast", model.CheckAuth, broadcast)
|
||||
ginServer.Handle("POST", "/api/broadcast/postMessage", model.CheckAuth, postMessage)
|
||||
ginServer.Handle("POST", "/api/broadcast/getChannels", model.CheckAuth, getChannels)
|
||||
ginServer.Handle("POST", "/api/broadcast/getChannelInfo", model.CheckAuth, getChannelInfo)
|
||||
ginServer.Handle("GET", "/ws/broadcast", model.CheckAuth, model.CheckAdminRole, broadcast)
|
||||
ginServer.Handle("POST", "/api/broadcast/postMessage", model.CheckAuth, model.CheckAdminRole, postMessage)
|
||||
ginServer.Handle("POST", "/api/broadcast/getChannels", model.CheckAuth, model.CheckAdminRole, getChannels)
|
||||
ginServer.Handle("POST", "/api/broadcast/getChannelInfo", model.CheckAuth, model.CheckAdminRole, getChannelInfo)
|
||||
|
||||
ginServer.Handle("POST", "/api/archive/zip", model.CheckAuth, model.CheckReadonly, zip)
|
||||
ginServer.Handle("POST", "/api/archive/unzip", model.CheckAuth, model.CheckReadonly, unzip)
|
||||
ginServer.Handle("POST", "/api/archive/zip", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, zip)
|
||||
ginServer.Handle("POST", "/api/archive/unzip", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, unzip)
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
"github.com/siyuan-note/siyuan/kernel/conf"
|
||||
"github.com/siyuan-note/siyuan/kernel/model"
|
||||
"github.com/siyuan-note/siyuan/kernel/server/proxy"
|
||||
"github.com/siyuan-note/siyuan/kernel/sql"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
@ -533,6 +534,58 @@ func setAppearance(c *gin.Context) {
|
|||
ret.Data = model.Conf.Appearance
|
||||
}
|
||||
|
||||
func setPublish(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
||||
arg, ok := util.JsonArg(c, ret)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
param, err := gulu.JSON.MarshalJSON(arg)
|
||||
if nil != err {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
publish := &conf.Publish{}
|
||||
if err = gulu.JSON.UnmarshalJSON(param, publish); nil != err {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
model.Conf.Publish = publish
|
||||
model.Conf.Save()
|
||||
|
||||
if port, err := proxy.InitPublishService(); err != nil {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
} else {
|
||||
ret.Data = map[string]any{
|
||||
"port": port,
|
||||
"publish": model.Conf.Publish,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getPublish(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
||||
if port, err := proxy.InitPublishService(); err != nil {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
} else {
|
||||
ret.Data = map[string]any{
|
||||
"port": port,
|
||||
"publish": model.Conf.Publish,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getCloudUser(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
|
|
@ -17,44 +17,17 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"mime"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/88250/gulu"
|
||||
"github.com/88250/lute/ast"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/siyuan-note/logging"
|
||||
"github.com/siyuan-note/siyuan/kernel/conf"
|
||||
"github.com/siyuan-note/siyuan/kernel/model"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
func serveSnippets(c *gin.Context) {
|
||||
filePath := strings.TrimPrefix(c.Request.URL.Path, "/snippets/")
|
||||
ext := filepath.Ext(filePath)
|
||||
name := strings.TrimSuffix(filePath, ext)
|
||||
confSnippets, err := model.LoadSnippets()
|
||||
if nil != err {
|
||||
logging.LogErrorf("load snippets failed: %s", err)
|
||||
c.Status(404)
|
||||
return
|
||||
}
|
||||
|
||||
for _, s := range confSnippets {
|
||||
if s.Name == name && ("" != ext && s.Type == ext[1:]) {
|
||||
c.Header("Content-Type", mime.TypeByExtension(ext))
|
||||
c.String(http.StatusOK, s.Content)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 没有在配置文件中命中时在文件系统上查找
|
||||
filePath = filepath.Join(util.SnippetsPath, filePath)
|
||||
c.File(filePath)
|
||||
}
|
||||
|
||||
func getSnippet(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/88250/lute"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
@ -25,6 +24,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/88250/lute"
|
||||
|
||||
"github.com/88250/gulu"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/siyuan-note/logging"
|
||||
|
@ -218,6 +219,17 @@ func getConf(c *gin.Context) {
|
|||
maskedConf.Sync.Stat = model.Conf.Language(53)
|
||||
}
|
||||
|
||||
// REF: https://github.com/siyuan-note/siyuan/issues/11364
|
||||
role := model.GetGinContextRole(c)
|
||||
if model.IsReadOnlyRole(role) {
|
||||
maskedConf.ReadOnly = true
|
||||
}
|
||||
if !model.IsValidRole(role, []model.Role{
|
||||
model.RoleAdministrator,
|
||||
}) {
|
||||
model.HideConfSecret(maskedConf)
|
||||
}
|
||||
|
||||
ret.Data = map[string]interface{}{
|
||||
"conf": maskedConf,
|
||||
"start": !util.IsUILoaded,
|
||||
|
|
45
kernel/conf/publish.go
Normal file
45
kernel/conf/publish.go
Normal file
|
@ -0,0 +1,45 @@
|
|||
// SiYuan - Refactor your thinking
|
||||
// Copyright (c) 2020-present, b3log.org
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package conf
|
||||
|
||||
type Publish struct {
|
||||
Enable bool `json:"enable"` // 是否启用发布服务
|
||||
Port uint16 `json:"port"` // 发布服务端口
|
||||
Auth *BasicAuth `json:"auth"` // Basic 认证
|
||||
}
|
||||
|
||||
type BasicAuth struct {
|
||||
Enable bool `json:"enable"` // 是否启用基础认证
|
||||
Accounts []*BasicAuthAccount `json:"accounts"` // 账户列表
|
||||
}
|
||||
|
||||
type BasicAuthAccount struct {
|
||||
Username string `json:"username"` // 用户名
|
||||
Password string `json:"password"` // 密码
|
||||
Memo string `json:"memo"` // 备注
|
||||
}
|
||||
|
||||
func NewPublish() *Publish {
|
||||
return &Publish{
|
||||
Enable: false,
|
||||
Port: 6808,
|
||||
Auth: &BasicAuth{
|
||||
Enable: true,
|
||||
Accounts: []*BasicAuthAccount{},
|
||||
},
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@ require (
|
|||
github.com/go-ole/go-ole v1.3.0
|
||||
github.com/goccy/go-json v0.10.3
|
||||
github.com/gofrs/flock v0.8.1
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/gorilla/css v1.0.1
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/imroc/req/v3 v3.43.7
|
||||
|
|
|
@ -154,6 +154,8 @@ github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
|||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
|
|
133
kernel/model/auth.go
Normal file
133
kernel/model/auth.go
Normal file
|
@ -0,0 +1,133 @@
|
|||
// SiYuan - Refactor your thinking
|
||||
// Copyright (c) 2020-present, b3log.org
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/siyuan-note/logging"
|
||||
)
|
||||
|
||||
type Account struct {
|
||||
Username string
|
||||
Password string
|
||||
Token string
|
||||
}
|
||||
type AccountsMap map[string]*Account
|
||||
type ClaimsKeyType string
|
||||
|
||||
const (
|
||||
XAuthTokenKey = "X-Auth-Token"
|
||||
|
||||
ClaimsContextKey = "claims"
|
||||
|
||||
iss = "siyuan-publish-reverse-proxy-server"
|
||||
sub = "publish"
|
||||
aud = "siyuan-kernel"
|
||||
|
||||
ClaimsKeyRole string = "role"
|
||||
)
|
||||
|
||||
var (
|
||||
accountsMap = AccountsMap{}
|
||||
|
||||
key = make([]byte, 32)
|
||||
)
|
||||
|
||||
func GetBasicAuthAccount(username string) *Account {
|
||||
return accountsMap[username]
|
||||
}
|
||||
|
||||
func InitAccounts() {
|
||||
accountsMap = AccountsMap{
|
||||
"": &Account{}, // 匿名用户
|
||||
}
|
||||
for _, account := range Conf.Publish.Auth.Accounts {
|
||||
accountsMap[account.Username] = &Account{
|
||||
Username: account.Username,
|
||||
Password: account.Password,
|
||||
}
|
||||
}
|
||||
|
||||
InitJWT()
|
||||
}
|
||||
|
||||
func InitJWT() {
|
||||
if _, err := rand.Read(key); err != nil {
|
||||
logging.LogErrorf("generate JWT signing key failed: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
for username, account := range accountsMap {
|
||||
// REF: https://golang-jwt.github.io/jwt/usage/create/
|
||||
t := jwt.NewWithClaims(
|
||||
jwt.SigningMethodHS256,
|
||||
jwt.MapClaims{
|
||||
"iss": iss,
|
||||
"sub": sub,
|
||||
"aud": aud,
|
||||
"jti": username,
|
||||
|
||||
ClaimsKeyRole: RoleReader,
|
||||
},
|
||||
)
|
||||
if token, err := t.SignedString(key); err != nil {
|
||||
logging.LogErrorf("JWT signature failed: %s", err)
|
||||
return
|
||||
} else {
|
||||
account.Token = token
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ParseJWT(tokenString string) (*jwt.Token, error) {
|
||||
// REF: https://golang-jwt.github.io/jwt/usage/parse/
|
||||
return jwt.Parse(
|
||||
tokenString,
|
||||
func(token *jwt.Token) (interface{}, error) {
|
||||
return key, nil
|
||||
},
|
||||
jwt.WithIssuer(iss),
|
||||
jwt.WithSubject(sub),
|
||||
jwt.WithAudience(aud),
|
||||
)
|
||||
}
|
||||
|
||||
func ParseXAuthToken(r *http.Request) *jwt.Token {
|
||||
tokenString := r.Header.Get(XAuthTokenKey)
|
||||
if tokenString != "" {
|
||||
if token, err := ParseJWT(tokenString); err != nil {
|
||||
logging.LogErrorf("JWT parse failed: %s", err)
|
||||
} else {
|
||||
return token
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetTokenClaims(token *jwt.Token) jwt.MapClaims {
|
||||
return token.Claims.(jwt.MapClaims)
|
||||
}
|
||||
|
||||
func GetClaimRole(claims jwt.MapClaims) Role {
|
||||
if role := claims[ClaimsKeyRole]; role != nil {
|
||||
return Role(role.(float64))
|
||||
}
|
||||
return RoleVisitor
|
||||
}
|
|
@ -76,6 +76,7 @@ type AppConf struct {
|
|||
Stat *conf.Stat `json:"stat"` // 统计
|
||||
Api *conf.API `json:"api"` // API
|
||||
Repo *conf.Repo `json:"repo"` // 数据仓库
|
||||
Publish *conf.Publish `json:"publish"` // 发布服务
|
||||
OpenHelp bool `json:"openHelp"` // 启动后是否需要打开用户指南
|
||||
ShowChangelog bool `json:"showChangelog"` // 是否显示版本更新日志
|
||||
CloudRegion int `json:"cloudRegion"` // 云端区域,0:中国大陆,1:北美
|
||||
|
@ -357,6 +358,10 @@ func InitConf() {
|
|||
Conf.Bazaar = conf.NewBazaar()
|
||||
}
|
||||
|
||||
if nil == Conf.Publish {
|
||||
Conf.Publish = conf.NewPublish()
|
||||
}
|
||||
|
||||
if nil == Conf.Repo {
|
||||
Conf.Repo = conf.NewRepo()
|
||||
}
|
||||
|
@ -894,6 +899,24 @@ func GetMaskedConf() (ret *AppConf, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// REF: https://github.com/siyuan-note/siyuan/issues/11364
|
||||
// HideConfSecret 隐藏设置中的秘密信息
|
||||
func HideConfSecret(c *AppConf) {
|
||||
c.AI = &conf.AI{}
|
||||
c.Api = &conf.API{}
|
||||
c.Flashcard = &conf.Flashcard{}
|
||||
c.LocalIPs = []string{}
|
||||
c.Publish = &conf.Publish{}
|
||||
c.Repo = &conf.Repo{}
|
||||
c.Sync = &conf.Sync{}
|
||||
c.System.AppDir = ""
|
||||
c.System.ConfDir = ""
|
||||
c.System.DataDir = ""
|
||||
c.System.HomeDir = ""
|
||||
c.System.Name = ""
|
||||
c.System.NetworkProxy = &conf.NetworkProxy{}
|
||||
}
|
||||
|
||||
func clearPortJSON() {
|
||||
pid := fmt.Sprintf("%d", os.Getpid())
|
||||
portJSON := filepath.Join(util.HomeDir, ".config", "siyuan", "port.json")
|
||||
|
|
56
kernel/model/role.go
Normal file
56
kernel/model/role.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
// SiYuan - Refactor your thinking
|
||||
// Copyright (c) 2020-present, b3log.org
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package model
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
|
||||
type Role uint
|
||||
|
||||
const (
|
||||
RoleContextKey = "role"
|
||||
)
|
||||
|
||||
const (
|
||||
RoleAdministrator Role = iota // 管理员
|
||||
RoleEditor // 编辑者
|
||||
RoleReader // 读者
|
||||
RoleVisitor // 匿名访问者
|
||||
)
|
||||
|
||||
func IsValidRole(role Role, roles []Role) bool {
|
||||
for _, role_ := range roles {
|
||||
if role == role_ {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsReadOnlyRole(role Role) bool {
|
||||
return IsValidRole(role, []Role{
|
||||
RoleReader,
|
||||
RoleVisitor,
|
||||
})
|
||||
}
|
||||
|
||||
func GetGinContextRole(c *gin.Context) Role {
|
||||
if role, exists := c.Get(RoleContextKey); exists {
|
||||
return role.(Role)
|
||||
} else {
|
||||
return RoleVisitor
|
||||
}
|
||||
}
|
|
@ -164,6 +164,16 @@ func CheckReadonly(c *gin.Context) {
|
|||
}
|
||||
|
||||
func CheckAuth(c *gin.Context) {
|
||||
// 已通过 JWT 认证
|
||||
if role := GetGinContextRole(c); IsValidRole(role, []Role{
|
||||
RoleAdministrator,
|
||||
RoleEditor,
|
||||
RoleReader,
|
||||
}) {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
//logging.LogInfof("check auth for [%s]", c.Request.RequestURI)
|
||||
localhost := util.IsLocalHost(c.Request.RemoteAddr)
|
||||
|
||||
|
@ -171,6 +181,7 @@ func CheckAuth(c *gin.Context) {
|
|||
if "" == Conf.AccessAuthCode {
|
||||
// Skip the empty access authorization code check https://github.com/siyuan-note/siyuan/issues/9709
|
||||
if util.SiyuanAccessAuthCodeBypass {
|
||||
c.Set(RoleContextKey, RoleAdministrator)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
@ -190,6 +201,7 @@ func CheckAuth(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
c.Set(RoleContextKey, RoleAdministrator)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
@ -206,19 +218,23 @@ func CheckAuth(c *gin.Context) {
|
|||
// 放过来自本机的某些请求
|
||||
if localhost {
|
||||
if strings.HasPrefix(c.Request.RequestURI, "/assets/") {
|
||||
c.Set(RoleContextKey, RoleAdministrator)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
if strings.HasPrefix(c.Request.RequestURI, "/api/system/exit") {
|
||||
c.Set(RoleContextKey, RoleAdministrator)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
if strings.HasPrefix(c.Request.RequestURI, "/api/system/getNetwork") {
|
||||
c.Set(RoleContextKey, RoleAdministrator)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
if strings.HasPrefix(c.Request.RequestURI, "/api/sync/performSync") {
|
||||
if util.ContainerIOS == util.Container || util.ContainerAndroid == util.Container {
|
||||
c.Set(RoleContextKey, RoleAdministrator)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
@ -229,6 +245,7 @@ func CheckAuth(c *gin.Context) {
|
|||
session := util.GetSession(c)
|
||||
workspaceSession := util.GetWorkspaceSession(session)
|
||||
if workspaceSession.AccessAuthCode == Conf.AccessAuthCode {
|
||||
c.Set(RoleContextKey, RoleAdministrator)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
@ -248,6 +265,7 @@ func CheckAuth(c *gin.Context) {
|
|||
|
||||
if "" != token {
|
||||
if Conf.Api.Token == token {
|
||||
c.Set(RoleContextKey, RoleAdministrator)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
@ -261,6 +279,7 @@ func CheckAuth(c *gin.Context) {
|
|||
// 通过 API token (query-params: token)
|
||||
if token := c.Query("token"); "" != token {
|
||||
if Conf.Api.Token == token {
|
||||
c.Set(RoleContextKey, RoleAdministrator)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
@ -300,9 +319,43 @@ func CheckAuth(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
c.Set(RoleContextKey, RoleAdministrator)
|
||||
c.Next()
|
||||
}
|
||||
|
||||
func CheckAdminRole(c *gin.Context) {
|
||||
if IsValidRole(GetGinContextRole(c), []Role{
|
||||
RoleAdministrator,
|
||||
}) {
|
||||
c.Next()
|
||||
} else {
|
||||
c.AbortWithStatus(http.StatusForbidden)
|
||||
}
|
||||
}
|
||||
|
||||
func CheckEditRole(c *gin.Context) {
|
||||
if IsValidRole(GetGinContextRole(c), []Role{
|
||||
RoleAdministrator,
|
||||
RoleEditor,
|
||||
}) {
|
||||
c.Next()
|
||||
} else {
|
||||
c.AbortWithStatus(http.StatusForbidden)
|
||||
}
|
||||
}
|
||||
|
||||
func CheckReadRole(c *gin.Context) {
|
||||
if IsValidRole(GetGinContextRole(c), []Role{
|
||||
RoleAdministrator,
|
||||
RoleEditor,
|
||||
RoleReader,
|
||||
}) {
|
||||
c.Next()
|
||||
} else {
|
||||
c.AbortWithStatus(http.StatusForbidden)
|
||||
}
|
||||
}
|
||||
|
||||
var timingAPIs = map[string]int{
|
||||
"/api/search/fullTextSearchBlock": 200, // Monitor the search performance and suggest solutions https://github.com/siyuan-note/siyuan/issues/7873
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package server
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
@ -65,7 +64,7 @@ func killRunningKernel() {
|
|||
}
|
||||
|
||||
func killByPort(port string) {
|
||||
if !isPortOpen(port) {
|
||||
if !util.IsPortOpen(port) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -87,19 +86,6 @@ func killByPort(port string) {
|
|||
logging.LogInfof("killed process [name=%s, pid=%s]", name, pid)
|
||||
}
|
||||
|
||||
func isPortOpen(port string) bool {
|
||||
timeout := time.Second
|
||||
conn, err := net.DialTimeout("tcp", net.JoinHostPort("127.0.0.1", port), timeout)
|
||||
if nil != err {
|
||||
return false
|
||||
}
|
||||
if nil != conn {
|
||||
conn.Close()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func kill(pid string) {
|
||||
var killCmd *exec.Cmd
|
||||
if gulu.OS.IsWindows() {
|
||||
|
|
41
kernel/server/proxy/fixedport.go
Normal file
41
kernel/server/proxy/fixedport.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
// SiYuan - Refactor your thinking
|
||||
// Copyright (c) 2020-present, b3log.org
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
|
||||
"github.com/siyuan-note/logging"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
func InitFixedPortService(host string) {
|
||||
if util.FixedPort != util.ServerPort {
|
||||
if util.IsPortOpen(util.FixedPort) {
|
||||
return
|
||||
}
|
||||
|
||||
// 启动一个固定 6806 端口的反向代理服务器,这样浏览器扩展才能直接使用 127.0.0.1:6806,不用配置端口
|
||||
proxy := httputil.NewSingleHostReverseProxy(util.ServerURL)
|
||||
logging.LogInfof("fixed port service [%s:%s] is running", host, util.FixedPort)
|
||||
if proxyErr := http.ListenAndServe(host+":"+util.FixedPort, proxy); nil != proxyErr {
|
||||
logging.LogWarnf("boot fixed port service [%s] failed: %s", util.ServerURL, proxyErr)
|
||||
}
|
||||
logging.LogInfof("fixed port service [%s:%s] is stopped", host, util.FixedPort)
|
||||
}
|
||||
}
|
161
kernel/server/proxy/publish.go
Normal file
161
kernel/server/proxy/publish.go
Normal file
|
@ -0,0 +1,161 @@
|
|||
// SiYuan - Refactor your thinking
|
||||
// Copyright (c) 2020-present, b3log.org
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"strconv"
|
||||
|
||||
"github.com/siyuan-note/logging"
|
||||
"github.com/siyuan-note/siyuan/kernel/model"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
type PublishServiceTransport struct{}
|
||||
|
||||
var (
|
||||
Host = "0.0.0.0"
|
||||
Port = "0"
|
||||
|
||||
listener net.Listener
|
||||
transport = PublishServiceTransport{}
|
||||
proxy = &httputil.ReverseProxy{
|
||||
Rewrite: rewrite,
|
||||
Transport: transport,
|
||||
}
|
||||
)
|
||||
|
||||
func InitPublishService() (uint16, error) {
|
||||
model.InitAccounts()
|
||||
|
||||
if listener != nil {
|
||||
if !model.Conf.Publish.Enable {
|
||||
// 关闭发布服务
|
||||
closePublishListener()
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if port, err := util.ParsePort(Port); err != nil {
|
||||
return 0, err
|
||||
} else if port != model.Conf.Publish.Port {
|
||||
// 关闭原端口的发布服务
|
||||
if err = closePublishListener(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 重新启动新端口的发布服务
|
||||
initPublishService()
|
||||
}
|
||||
} else {
|
||||
if !model.Conf.Publish.Enable {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// 启动新端口的发布服务
|
||||
initPublishService()
|
||||
}
|
||||
return util.ParsePort(Port)
|
||||
}
|
||||
|
||||
func initPublishService() (err error) {
|
||||
if err = initPublishListener(); err == nil {
|
||||
go startPublishReverseProxyService()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func initPublishListener() (err error) {
|
||||
// Start new listener
|
||||
listener, err = net.Listen("tcp", fmt.Sprintf("%s:%d", Host, model.Conf.Publish.Port))
|
||||
if err != nil {
|
||||
logging.LogErrorf("start listener failed: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
_, Port, err = net.SplitHostPort(listener.Addr().String())
|
||||
if nil != err {
|
||||
logging.LogErrorf("split host and port failed: %s", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func closePublishListener() (err error) {
|
||||
listener_ := listener
|
||||
listener = nil
|
||||
if err = listener_.Close(); err != nil {
|
||||
logging.LogErrorf("close listener %s failed: %s", listener_.Addr().String(), err)
|
||||
listener = listener_
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func startPublishReverseProxyService() {
|
||||
logging.LogInfof("publish service [%s:%s] is running", Host, Port)
|
||||
// 服务进行时一直阻塞
|
||||
if err := http.Serve(listener, proxy); nil != err {
|
||||
if listener != nil {
|
||||
logging.LogErrorf("boot publish service failed: %s", err)
|
||||
}
|
||||
}
|
||||
logging.LogInfof("publish service [%s:%s] is stopped", Host, Port)
|
||||
}
|
||||
|
||||
func rewrite(r *httputil.ProxyRequest) {
|
||||
r.SetURL(util.ServerURL)
|
||||
r.SetXForwarded()
|
||||
// r.Out.Host = r.In.Host // if desired
|
||||
}
|
||||
|
||||
func (PublishServiceTransport) RoundTrip(request *http.Request) (response *http.Response, err error) {
|
||||
if model.Conf.Publish.Auth.Enable {
|
||||
// Basic Auth
|
||||
username, password, ok := request.BasicAuth()
|
||||
account := model.GetBasicAuthAccount(username)
|
||||
|
||||
if !ok ||
|
||||
account == nil ||
|
||||
account.Username == "" || // 匿名用户
|
||||
account.Password != password {
|
||||
|
||||
return &http.Response{
|
||||
StatusCode: http.StatusUnauthorized,
|
||||
Status: http.StatusText(http.StatusUnauthorized),
|
||||
Proto: request.Proto,
|
||||
ProtoMajor: request.ProtoMajor,
|
||||
ProtoMinor: request.ProtoMinor,
|
||||
Request: request,
|
||||
Header: http.Header{
|
||||
"WWW-Authenticate": {"Basic realm=" + strconv.Quote("Authorization Required")},
|
||||
},
|
||||
Close: false,
|
||||
ContentLength: -1,
|
||||
}, nil
|
||||
} else {
|
||||
// set JWT
|
||||
request.Header.Set(model.XAuthTokenKey, account.Token)
|
||||
}
|
||||
} else {
|
||||
request.Header.Set(model.XAuthTokenKey, model.GetBasicAuthAccount("").Token)
|
||||
}
|
||||
|
||||
response, err = http.DefaultTransport.RoundTrip(request)
|
||||
return
|
||||
}
|
|
@ -20,9 +20,9 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"mime"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/http/pprof"
|
||||
"net/url"
|
||||
"os"
|
||||
|
@ -42,10 +42,13 @@ import (
|
|||
"github.com/siyuan-note/siyuan/kernel/api"
|
||||
"github.com/siyuan-note/siyuan/kernel/cmd"
|
||||
"github.com/siyuan-note/siyuan/kernel/model"
|
||||
"github.com/siyuan-note/siyuan/kernel/server/proxy"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
var cookieStore = cookie.NewStore([]byte("ATN51UlxVq1Gcvdf"))
|
||||
var (
|
||||
cookieStore = cookie.NewStore([]byte("ATN51UlxVq1Gcvdf"))
|
||||
)
|
||||
|
||||
func Serve(fastMode bool) {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
|
@ -57,6 +60,7 @@ func Serve(fastMode bool) {
|
|||
model.Timing,
|
||||
model.Recover,
|
||||
corsMiddleware(), // 后端服务支持 CORS 预检请求验证 https://github.com/siyuan-note/siyuan/pull/5593
|
||||
jwtMiddleware, // 解析 JWT https://github.com/siyuan-note/siyuan/issues/11364
|
||||
gzip.Gzip(gzip.DefaultCompression, gzip.WithExcludedExtensions([]string{".pdf", ".mp3", ".wav", ".ogg", ".mov", ".weba", ".mkv", ".mp4", ".webm"})),
|
||||
)
|
||||
|
||||
|
@ -78,7 +82,10 @@ func Serve(fastMode bool) {
|
|||
serveEmojis(ginServer)
|
||||
serveTemplates(ginServer)
|
||||
servePublic(ginServer)
|
||||
serveSnippets(ginServer)
|
||||
serveRepoDiff(ginServer)
|
||||
serveCheckAuth(ginServer)
|
||||
serveFixedStaticFiles(ginServer)
|
||||
api.ServeAPI(ginServer)
|
||||
|
||||
var host string
|
||||
|
@ -108,34 +115,27 @@ func Serve(fastMode bool) {
|
|||
}
|
||||
util.ServerPort = port
|
||||
|
||||
util.ServerURL, err = url.Parse("http://127.0.0.1:" + port)
|
||||
if err != nil {
|
||||
logging.LogErrorf("parse server url failed: %s", err)
|
||||
}
|
||||
|
||||
pid := fmt.Sprintf("%d", os.Getpid())
|
||||
if !fastMode {
|
||||
rewritePortJSON(pid, port)
|
||||
}
|
||||
|
||||
logging.LogInfof("kernel [pid=%s] http server [%s] is booting", pid, host+":"+port)
|
||||
util.HttpServing = true
|
||||
|
||||
go util.HookUILoaded()
|
||||
|
||||
go func() {
|
||||
time.Sleep(1 * time.Second)
|
||||
if util.FixedPort != port {
|
||||
if isPortOpen(util.FixedPort) {
|
||||
return
|
||||
}
|
||||
|
||||
// 启动一个 6806 端口的反向代理服务器,这样浏览器扩展才能直接使用 127.0.0.1:6806,不用配置端口
|
||||
serverURL, _ := url.Parse("http://127.0.0.1:" + port)
|
||||
proxy := httputil.NewSingleHostReverseProxy(serverURL)
|
||||
logging.LogInfof("reverse proxy server [%s] is booting", host+":"+util.FixedPort)
|
||||
if proxyErr := http.ListenAndServe(host+":"+util.FixedPort, proxy); nil != proxyErr {
|
||||
logging.LogWarnf("boot reverse proxy server [%s] failed: %s", serverURL, proxyErr)
|
||||
}
|
||||
// 反代服务器启动失败不影响核心服务器启动
|
||||
}
|
||||
go proxy.InitFixedPortService(host)
|
||||
go proxy.InitPublishService()
|
||||
// 反代服务器启动失败不影响核心服务器启动
|
||||
}()
|
||||
|
||||
go util.HookUILoaded()
|
||||
|
||||
if err = http.Serve(ln, ginServer.Handler()); nil != err {
|
||||
if !fastMode {
|
||||
logging.LogErrorf("boot kernel failed: %s", err)
|
||||
|
@ -196,11 +196,33 @@ func servePublic(ginServer *gin.Engine) {
|
|||
ginServer.Static("/public/", filepath.Join(util.DataDir, "public"))
|
||||
}
|
||||
|
||||
func serveAppearance(ginServer *gin.Engine) {
|
||||
ginServer.StaticFile("favicon.ico", filepath.Join(util.WorkingDir, "stage", "icon.png"))
|
||||
ginServer.StaticFile("manifest.json", filepath.Join(util.WorkingDir, "stage", "manifest.webmanifest"))
|
||||
ginServer.StaticFile("manifest.webmanifest", filepath.Join(util.WorkingDir, "stage", "manifest.webmanifest"))
|
||||
func serveSnippets(ginServer *gin.Engine) {
|
||||
ginServer.Handle("GET", "/snippets/*filepath", func(c *gin.Context) {
|
||||
filePath := strings.TrimPrefix(c.Request.URL.Path, "/snippets/")
|
||||
ext := filepath.Ext(filePath)
|
||||
name := strings.TrimSuffix(filePath, ext)
|
||||
confSnippets, err := model.LoadSnippets()
|
||||
if nil != err {
|
||||
logging.LogErrorf("load snippets failed: %s", err)
|
||||
c.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
for _, s := range confSnippets {
|
||||
if s.Name == name && ("" != ext && s.Type == ext[1:]) {
|
||||
c.Header("Content-Type", mime.TypeByExtension(ext))
|
||||
c.String(http.StatusOK, s.Content)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 没有在配置文件中命中时在文件系统上查找
|
||||
filePath = filepath.Join(util.SnippetsPath, filePath)
|
||||
c.File(filePath)
|
||||
})
|
||||
}
|
||||
|
||||
func serveAppearance(ginServer *gin.Engine) {
|
||||
siyuan := ginServer.Group("", model.CheckAuth)
|
||||
|
||||
siyuan.Handle("GET", "/", func(c *gin.Context) {
|
||||
|
@ -295,12 +317,13 @@ func serveAppearance(ginServer *gin.Engine) {
|
|||
})
|
||||
|
||||
siyuan.Static("/stage/", filepath.Join(util.WorkingDir, "stage"))
|
||||
ginServer.StaticFile("service-worker.js", filepath.Join(util.WorkingDir, "stage", "service-worker.js"))
|
||||
|
||||
siyuan.GET("/check-auth", serveCheckAuth)
|
||||
}
|
||||
|
||||
func serveCheckAuth(c *gin.Context) {
|
||||
func serveCheckAuth(ginServer *gin.Engine) {
|
||||
ginServer.GET("/check-auth", serveAuthPage)
|
||||
}
|
||||
|
||||
func serveAuthPage(c *gin.Context) {
|
||||
data, err := os.ReadFile(filepath.Join(util.WorkingDir, "stage/auth.html"))
|
||||
if nil != err {
|
||||
logging.LogErrorf("load auth page failed: %s", err)
|
||||
|
@ -363,20 +386,20 @@ func serveCheckAuth(c *gin.Context) {
|
|||
}
|
||||
|
||||
func serveAssets(ginServer *gin.Engine) {
|
||||
ginServer.POST("/upload", model.CheckAuth, model.Upload)
|
||||
ginServer.POST("/upload", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, model.Upload)
|
||||
|
||||
ginServer.GET("/assets/*path", model.CheckAuth, func(context *gin.Context) {
|
||||
requestPath := context.Param("path")
|
||||
relativePath := path.Join("assets", requestPath)
|
||||
p, err := model.GetAssetAbsPath(relativePath)
|
||||
if nil != err {
|
||||
context.Status(404)
|
||||
context.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
http.ServeFile(context.Writer, context.Request, p)
|
||||
return
|
||||
})
|
||||
ginServer.GET("/history/*path", model.CheckAuth, func(context *gin.Context) {
|
||||
ginServer.GET("/history/*path", model.CheckAuth, model.CheckAdminRole, func(context *gin.Context) {
|
||||
p := filepath.Join(util.HistoryDir, context.Param("path"))
|
||||
http.ServeFile(context.Writer, context.Request, p)
|
||||
return
|
||||
|
@ -384,7 +407,7 @@ func serveAssets(ginServer *gin.Engine) {
|
|||
}
|
||||
|
||||
func serveRepoDiff(ginServer *gin.Engine) {
|
||||
ginServer.GET("/repo/diff/*path", model.CheckAuth, func(context *gin.Context) {
|
||||
ginServer.GET("/repo/diff/*path", model.CheckAuth, model.CheckAdminRole, func(context *gin.Context) {
|
||||
requestPath := context.Param("path")
|
||||
p := filepath.Join(util.TempDir, "repo", "diff", requestPath)
|
||||
http.ServeFile(context.Writer, context.Request, p)
|
||||
|
@ -451,6 +474,17 @@ func serveWebSocket(ginServer *gin.Engine) {
|
|||
}
|
||||
}
|
||||
|
||||
// REF: https://github.com/siyuan-note/siyuan/issues/11364
|
||||
if !authOk {
|
||||
if token := model.ParseXAuthToken(s.Request); token != nil {
|
||||
authOk = token.Valid && model.IsValidRole(model.GetClaimRole(model.GetTokenClaims(token)), []model.Role{
|
||||
model.RoleAdministrator,
|
||||
model.RoleEditor,
|
||||
model.RoleReader,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if !authOk {
|
||||
// 用于授权页保持连接,避免非常驻内存内核自动退出 https://github.com/siyuan-note/insider/issues/1099
|
||||
authOk = strings.Contains(s.Request.RequestURI, "/ws?app=siyuan&id=auth")
|
||||
|
@ -516,12 +550,24 @@ func serveWebSocket(ginServer *gin.Engine) {
|
|||
s.Write(result.Bytes())
|
||||
return
|
||||
}
|
||||
if util.ReadOnly && !command.IsRead() {
|
||||
result := util.NewResult()
|
||||
result.Code = -1
|
||||
result.Msg = model.Conf.Language(34)
|
||||
s.Write(result.Bytes())
|
||||
return
|
||||
if !command.IsRead() {
|
||||
readonly := util.ReadOnly
|
||||
if !readonly {
|
||||
if token := model.ParseXAuthToken(s.Request); token != nil {
|
||||
readonly = token.Valid && model.IsValidRole(model.GetClaimRole(model.GetTokenClaims(token)), []model.Role{
|
||||
model.RoleReader,
|
||||
model.RoleVisitor,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if readonly {
|
||||
result := util.NewResult()
|
||||
result.Code = -1
|
||||
result.Msg = model.Conf.Language(34)
|
||||
s.Write(result.Bytes())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
end := time.Now()
|
||||
|
@ -564,3 +610,30 @@ func corsMiddleware() gin.HandlerFunc {
|
|||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// jwtMiddleware is a middleware to check jwt token
|
||||
// REF: https://github.com/siyuan-note/siyuan/issues/11364
|
||||
func jwtMiddleware(c *gin.Context) {
|
||||
if token := model.ParseXAuthToken(c.Request); token != nil {
|
||||
// c.Request.Header.Del(model.XAuthTokenKey)
|
||||
if token.Valid {
|
||||
claims := model.GetTokenClaims(token)
|
||||
c.Set(model.ClaimsContextKey, claims)
|
||||
c.Set(model.RoleContextKey, model.GetClaimRole(claims))
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
}
|
||||
c.Set(model.RoleContextKey, model.RoleVisitor)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
func serveFixedStaticFiles(ginServer *gin.Engine) {
|
||||
ginServer.StaticFile("favicon.ico", filepath.Join(util.WorkingDir, "stage", "icon.png"))
|
||||
|
||||
ginServer.StaticFile("manifest.json", filepath.Join(util.WorkingDir, "stage", "manifest.webmanifest"))
|
||||
ginServer.StaticFile("manifest.webmanifest", filepath.Join(util.WorkingDir, "stage", "manifest.webmanifest"))
|
||||
|
||||
ginServer.StaticFile("service-worker.js", filepath.Join(util.WorkingDir, "stage", "service-worker.js"))
|
||||
}
|
||||
|
|
|
@ -18,10 +18,11 @@ package sql
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
"github.com/siyuan-note/filelock"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/siyuan-note/filelock"
|
||||
|
||||
"github.com/88250/lute/ast"
|
||||
"github.com/siyuan-note/logging"
|
||||
"github.com/siyuan-note/siyuan/kernel/treenode"
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -90,6 +91,19 @@ func IsOnline(checkURL string, skipTlsVerify bool) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func IsPortOpen(port string) bool {
|
||||
timeout := time.Second
|
||||
conn, err := net.DialTimeout("tcp", net.JoinHostPort("127.0.0.1", port), timeout)
|
||||
if nil != err {
|
||||
return false
|
||||
}
|
||||
if nil != conn {
|
||||
conn.Close()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isOnline(checkURL string, skipTlsVerify bool) (ret bool) {
|
||||
c := req.C().SetTimeout(3 * time.Second)
|
||||
if skipTlsVerify {
|
||||
|
@ -168,3 +182,12 @@ func initHttpClient() {
|
|||
http.DefaultClient = httpclient.GetCloudFileClient2Min()
|
||||
http.DefaultTransport = httpclient.NewTransport(false)
|
||||
}
|
||||
|
||||
func ParsePort(portString string) (uint16, error) {
|
||||
if port, err := strconv.ParseUint(portString, 10, 16); err != nil {
|
||||
logging.LogErrorf("parse port [%s] failed: %s", portString, err)
|
||||
return 0, err
|
||||
} else {
|
||||
return uint16(port), nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -269,6 +269,7 @@ func IsDisplayableAsset(p string) bool {
|
|||
|
||||
func GetAbsPathInWorkspace(relPath string) (string, error) {
|
||||
absPath := filepath.Join(WorkspaceDir, relPath)
|
||||
absPath = filepath.Clean(absPath)
|
||||
if WorkspaceDir == absPath {
|
||||
return absPath, nil
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"fmt"
|
||||
"math/rand"
|
||||
"mime"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
@ -341,7 +342,9 @@ func WriteWorkspacePaths(workspacePaths []string) (err error) {
|
|||
}
|
||||
|
||||
var (
|
||||
ServerPort = "0" // HTTP/WebSocket 端口,0 为使用随机端口
|
||||
ServerURL *url.URL // 内核服务 URL
|
||||
ServerPort = "0" // HTTP/WebSocket 端口,0 为使用随机端口
|
||||
|
||||
ReadOnly bool
|
||||
AccessAuthCode string
|
||||
Lang = ""
|
||||
|
|
Loading…
Add table
Reference in a new issue