CVE-2024-29028 (published 2024-04-19T15:15Z)

memos is a privacy-first, lightweight note-taking service. In memos 0.13.2, an SSRF vulnerability exists at the /o/get/httpmeta that allows unauthenticated users to enumerate the internal network and receive limited html values in json form. This vulnerability is fixed in 0.16.1.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/usememos/memos
commit_details: repo_url: https://github.com/usememos/memos
author: Steven
author_date: 2023-10-06 23:03:36+08:00
msg: chore: remove unused httpmeta getter api
repository: repo_url: https://github.com/usememos/memos
repo_name: usememos/memos
description: An open source, lightweight note-taking service. Easily capture and share your great thoughts.
repo_language: Go
owner: usememos
file_changes: filename: docs.go
change_type: ModificationType.MODIFY
diff: @@ -1891,40 +1891,6 @@ const docTemplate = `{
                 }
             }
         },
-        "/o/get/GetWebsiteMetadata": {
-            "get": {
-                "produces": [
-                    "application/json"
-                ],
-                "tags": [
-                    "get"
-                ],
-                "summary": "Get website metadata",
-                "parameters": [
-                    {
-                        "type": "string",
-                        "description": "Website URL",
-                        "name": "url",
-                        "in": "query",
-                        "required": true
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "description": "Extracted metadata",
-                        "schema": {
-                            "$ref": "#/definitions/getter.HTMLMeta"
-                        }
-                    },
-                    "400": {
-                        "description": "Missing website url | Wrong url"
-                    },
-                    "406": {
-                        "description": "Failed to get website meta with url: %s"
-                    }
-                }
-            }
-        },
         "/o/r/{resourceId}": {
             "get": {
                 "description": "*Swagger UI may have problems displaying other file types than images",
@@ -2002,20 +1968,6 @@ const docTemplate = `{
         }
     },
     "definitions": {
-        "getter.HTMLMeta": {
-            "type": "object",
-            "properties": {
-                "description": {
-                    "type": "string"
-                },
-                "image": {
-                    "type": "string"
-                },
-                "title": {
-                    "type": "string"
-                }
-            }
-        },
         "github_com_usememos_memos_store.UserSetting": {
             "type": "object",
             "properties": {
@@ -2033,6 +1985,14 @@ const docTemplate = `{
         "profile.Profile": {
             "type": "object",
             "properties": {
+                "driver": {
+                    "description": "Driver is the database driver\nsqlite, mysql",
+                    "type": "string"
+                },
+                "dsn": {
+                    "description": "DSN points to where Memos stores its own data",
+                    "type": "string"
+                },
                 "mode": {
                     "description": "Mode can be \"prod\" or \"dev\" or \"demo\"",
                     "type": "string"
@@ -2139,8 +2099,11 @@ const docTemplate = `{
                 "id": {
                     "type": "integer"
                 },
+                "parentID": {
+                    "description": "Composed fields\nFor those comment memos, the parent ID is the memo ID of the memo being commented.\nIf the parent ID is nil, then this memo is not a comment.",
+                    "type": "integer"
+                },
                 "pinned": {
-                    "description": "Composed fields",
                     "type": "boolean"
                 },
                 "relationList": {
@@ -2189,11 +2152,11 @@ const docTemplate = `{
             "type": "string",
             "enum": [
                 "REFERENCE",
-                "ADDITIONAL"
+                "COMMENT"
             ],
             "x-enum-varnames": [
                 "MemoRelationReference",
-                "MemoRelationAdditional"
+                "MemoRelationComment"
             ]
         },
         "store.Resource": {
@@ -2406,9 +2369,6 @@ const docTemplate = `{
                 "filename": {
                     "type": "string"
                 },
-                "internalPath": {
-                    "type": "string"
-                },
                 "type": {
                     "type": "string"
                 }

programming_language: Swift
filename: http_getter.go
change_type: ModificationType.MODIFY
diff: @@ -11,39 +11,10 @@ import (
 )
 
 func (*APIV1Service) registerGetterPublicRoutes(g *echo.Group) {
-	// GET /get/httpmeta?url={url} - Get website meta.
-	g.GET("/get/httpmeta", GetWebsiteMetadata)
-
 	// GET /get/image?url={url} - Get image.
 	g.GET("/get/image", GetImage)
 }
 
-// GetWebsiteMetadata godoc
-//
-//	@Summary	Get website metadata
-//	@Tags		get
-//	@Produce	json
-//	@Param		url	query		string			true	"Website URL"
-//	@Success	200	{object}	getter.HTMLMeta	"Extracted metadata"
-//	@Failure	400	{object}	nil				"Missing website url | Wrong url"
-//	@Failure	406	{object}	nil				"Failed to get website meta with url: %s"
-//	@Router		/o/get/GetWebsiteMetadata [GET]
-func GetWebsiteMetadata(c echo.Context) error {
-	urlStr := c.QueryParam("url")
-	if urlStr == "" {
-		return echo.NewHTTPError(http.StatusBadRequest, "Missing website url")
-	}
-	if _, err := url.Parse(urlStr); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, "Wrong url").SetInternal(err)
-	}
-
-	htmlMeta, err := getter.GetHTMLMeta(urlStr)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusNotAcceptable, fmt.Sprintf("Failed to get website meta with url: %s", urlStr)).SetInternal(err)
-	}
-	return c.JSON(http.StatusOK, htmlMeta)
-}
-
 // GetImage godoc
 //
 //	@Summary	Get GetImage from URL

programming_language: Go
filename: swagger.yaml
change_type: ModificationType.MODIFY
diff: @@ -1,14 +1,5 @@
 basePath: /
 definitions:
-  getter.HTMLMeta:
-    properties:
-      description:
-        type: string
-      image:
-        type: string
-      title:
-        type: string
-    type: object
   github_com_usememos_memos_store.UserSetting:
     properties:
       key:
@@ -20,6 +11,14 @@ definitions:
     type: object
   profile.Profile:
     properties:
+      driver:
+        description: |-
+          Driver is the database driver
+          sqlite, mysql
+        type: string
+      dsn:
+        description: DSN points to where Memos stores its own data
+        type: string
       mode:
         description: Mode can be "prod" or "dev" or "demo"
         type: string
@@ -90,8 +89,13 @@ definitions:
         type: integer
       id:
         type: integer
+      parentID:
+        description: |-
+          Composed fields
+          For those comment memos, the parent ID is the memo ID of the memo being commented.
+          If the parent ID is nil, then this memo is not a comment.
+        type: integer
       pinned:
-        description: Composed fields
         type: boolean
       relationList:
         items:
@@ -122,11 +126,11 @@ definitions:
   store.MemoRelationType:
     enum:
     - REFERENCE
-    - ADDITIONAL
+    - COMMENT
     type: string
     x-enum-varnames:
     - MemoRelationReference
-    - MemoRelationAdditional
+    - MemoRelationComment
   store.Resource:
     properties:
       blob:
@@ -267,8 +271,6 @@ definitions:
         type: string
       filename:
         type: string
-      internalPath:
-        type: string
       type:
         type: string
     type: object
@@ -1976,28 +1978,6 @@ paths:
       summary: Get GetImage from URL
       tags:
       - get
-  /o/get/GetWebsiteMetadata:
-    get:
-      parameters:
-      - description: Website URL
-        in: query
-        name: url
-        required: true
-        type: string
-      produces:
-      - application/json
-      responses:
-        "200":
-          description: Extracted metadata
-          schema:
-            $ref: '#/definitions/getter.HTMLMeta'
-        "400":
-          description: Missing website url | Wrong url
-        "406":
-          description: 'Failed to get website meta with url: %s'
-      summary: Get website metadata
-      tags:
-      - get
   /o/r/{resourceId}:
     get:
       description: '*Swagger UI may have problems displaying other file types than

programming_language: CoffeeScript
filename: v1.md
change_type: ModificationType.MODIFY
diff: @@ -1,234 +1,249 @@
 # memos API
+
 A privacy-first, lightweight note-taking service.
 
 ## Version: 1.0
 
 **Contact information:**  
 API Support  
-<https://github.com/orgs/usememos/discussions>  
+<https://github.com/orgs/usememos/discussions>
 
 **License:** [MIT License](https://github.com/usememos/memos/blob/main/LICENSE)
 
 [Find out more about Memos.](https://usememos.com/)
 
 ---
+
 ### /api/v1/auth/signin
 
 #### POST
+
 ##### Summary
 
 Sign-in to memos.
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| body | body | Sign-in object | Yes | [v1.SignIn](#v1signin) |
+| Name | Located in | Description    | Required | Schema                 |
+| ---- | ---------- | -------------- | -------- | ---------------------- |
+| body | body       | Sign-in object | Yes      | [v1.SignIn](#v1signin) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | User information | [store.User](#storeuser) |
-| 400 | Malformatted signin request |  |
-| 401 | Password login is deactivated \| Incorrect login credentials, please try again |  |
-| 403 | User has been archived with username %s |  |
-| 500 | Failed to find system setting \| Failed to unmarshal system setting \| Incorrect login credentials, please try again \| Failed to generate tokens \| Failed to create activity |  |
+| Code | Description                                                                                                                                                                    | Schema                   |
+| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------ |
+| 200  | User information                                                                                                                                                               | [store.User](#storeuser) |
+| 400  | Malformatted signin request                                                                                                                                                    |                          |
+| 401  | Password login is deactivated \| Incorrect login credentials, please try again                                                                                                 |                          |
+| 403  | User has been archived with username %s                                                                                                                                        |                          |
+| 500  | Failed to find system setting \| Failed to unmarshal system setting \| Incorrect login credentials, please try again \| Failed to generate tokens \| Failed to create activity |                          |
 
 ### /api/v1/auth/signin/sso
 
 #### POST
+
 ##### Summary
 
 Sign-in to memos using SSO.
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| body | body | SSO sign-in object | Yes | [v1.SSOSignIn](#v1ssosignin) |
+| Name | Located in | Description        | Required | Schema                       |
+| ---- | ---------- | ------------------ | -------- | ---------------------------- |
+| body | body       | SSO sign-in object | Yes      | [v1.SSOSignIn](#v1ssosignin) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | User information | [store.User](#storeuser) |
-| 400 | Malformatted signin request |  |
-| 401 | Access denied, identifier does not match the filter. |  |
-| 403 | User has been archived with username {username} |  |
-| 404 | Identity provider not found |  |
-| 500 | Failed to find identity provider \| Failed to create identity provider instance \| Failed to exchange token \| Failed to get user info \| Failed to compile identifier filter \| Incorrect login credentials, please try again \| Failed to generate random password \| Failed to generate password hash \| Failed to create user \| Failed to generate tokens \| Failed to create activity |  |
+| Code | Description                                                                                                                                                                                                                                                                                                                                                                                 | Schema                   |
+| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
+| 200  | User information                                                                                                                                                                                                                                                                                                                                                                            | [store.User](#storeuser) |
+| 400  | Malformatted signin request                                                                                                                                                                                                                                                                                                                                                                 |                          |
+| 401  | Access denied, identifier does not match the filter.                                                                                                                                                                                                                                                                                                                                        |                          |
+| 403  | User has been archived with username {username}                                                                                                                                                                                                                                                                                                                                             |                          |
+| 404  | Identity provider not found                                                                                                                                                                                                                                                                                                                                                                 |                          |
+| 500  | Failed to find identity provider \| Failed to create identity provider instance \| Failed to exchange token \| Failed to get user info \| Failed to compile identifier filter \| Incorrect login credentials, please try again \| Failed to generate random password \| Failed to generate password hash \| Failed to create user \| Failed to generate tokens \| Failed to create activity |                          |
 
 ### /api/v1/auth/signout
 
 #### POST
+
 ##### Summary
 
 Sign-out from memos.
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Sign-out success | boolean |
+| Code | Description      | Schema  |
+| ---- | ---------------- | ------- |
+| 200  | Sign-out success | boolean |
 
 ### /api/v1/auth/signup
 
 #### POST
+
 ##### Summary
 
 Sign-up to memos.
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| body | body | Sign-up object | Yes | [v1.SignUp](#v1signup) |
+| Name | Located in | Description    | Required | Schema                 |
+| ---- | ---------- | -------------- | -------- | ---------------------- |
+| body | body       | Sign-up object | Yes      | [v1.SignUp](#v1signup) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | User information | [store.User](#storeuser) |
-| 400 | Malformatted signup request \| Failed to find users |  |
-| 401 | signup is disabled |  |
-| 403 | Forbidden |  |
-| 404 | Not found |  |
-| 500 | Failed to find system setting \| Failed to unmarshal system setting allow signup \| Failed to generate password hash \| Failed to create user \| Failed to generate tokens \| Failed to create activity |  |
+| Code | Description                                                                                                                                                                                             | Schema                   |
+| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
+| 200  | User information                                                                                                                                                                                        | [store.User](#storeuser) |
+| 400  | Malformatted signup request \| Failed to find users                                                                                                                                                     |                          |
+| 401  | signup is disabled                                                                                                                                                                                      |                          |
+| 403  | Forbidden                                                                                                                                                                                               |                          |
+| 404  | Not found                                                                                                                                                                                               |                          |
+| 500  | Failed to find system setting \| Failed to unmarshal system setting allow signup \| Failed to generate password hash \| Failed to create user \| Failed to generate tokens \| Failed to create activity |                          |
 
 ---
+
 ### /api/v1/idp
 
 #### GET
+
 ##### Summary
 
 Get a list of identity providers
 
 ##### Description
 
-*clientSecret is only available for host user
+\*clientSecret is only available for host user
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | List of available identity providers | [ [v1.IdentityProvider](#v1identityprovider) ] |
-| 500 | Failed to find identity provider list \| Failed to find user |  |
+| Code | Description                                                  | Schema                                         |
+| ---- | ------------------------------------------------------------ | ---------------------------------------------- |
+| 200  | List of available identity providers                         | [ [v1.IdentityProvider](#v1identityprovider) ] |
+| 500  | Failed to find identity provider list \| Failed to find user |                                                |
 
 #### POST
+
 ##### Summary
 
 Create Identity Provider
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| body | body | Identity provider information | Yes | [v1.CreateIdentityProviderRequest](#v1createidentityproviderrequest) |
+| Name | Located in | Description                   | Required | Schema                                                               |
+| ---- | ---------- | ----------------------------- | -------- | -------------------------------------------------------------------- |
+| body | body       | Identity provider information | Yes      | [v1.CreateIdentityProviderRequest](#v1createidentityproviderrequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Identity provider information | [store.IdentityProvider](#storeidentityprovider) |
-| 400 | Malformatted post identity provider request |  |
-| 401 | Missing user in session \| Unauthorized |  |
-| 500 | Failed to find user \| Failed to create identity provider |  |
+| Code | Description                                               | Schema                                           |
+| ---- | --------------------------------------------------------- | ------------------------------------------------ |
+| 200  | Identity provider information                             | [store.IdentityProvider](#storeidentityprovider) |
+| 400  | Malformatted post identity provider request               |                                                  |
+| 401  | Missing user in session \| Unauthorized                   |                                                  |
+| 500  | Failed to find user \| Failed to create identity provider |                                                  |
 
 ### /api/v1/idp/{idpId}
 
 #### DELETE
+
 ##### Summary
 
 Delete an identity provider by ID
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| idpId | path | Identity Provider ID | Yes | integer |
+| Name  | Located in | Description          | Required | Schema  |
+| ----- | ---------- | -------------------- | -------- | ------- |
+| idpId | path       | Identity Provider ID | Yes      | integer |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Identity Provider deleted | boolean |
-| 400 | ID is not a number: %s \| Malformatted patch identity provider request |  |
-| 401 | Missing user in session \| Unauthorized |  |
-| 500 | Failed to find user \| Failed to patch identity provider |  |
+| Code | Description                                                            | Schema  |
+| ---- | ---------------------------------------------------------------------- | ------- |
+| 200  | Identity Provider deleted                                              | boolean |
+| 400  | ID is not a number: %s \| Malformatted patch identity provider request |         |
+| 401  | Missing user in session \| Unauthorized                                |         |
+| 500  | Failed to find user \| Failed to patch identity provider               |         |
 
 #### GET
+
 ##### Summary
 
 Get an identity provider by ID
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| idpId | path | Identity provider ID | Yes | integer |
+| Name  | Located in | Description          | Required | Schema  |
+| ----- | ---------- | -------------------- | -------- | ------- |
+| idpId | path       | Identity provider ID | Yes      | integer |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Requested identity provider | [store.IdentityProvider](#storeidentityprovider) |
-| 400 | ID is not a number: %s |  |
-| 401 | Missing user in session \| Unauthorized |  |
-| 404 | Identity provider not found |  |
-| 500 | Failed to find identity provider list \| Failed to find user |  |
+| Code | Description                                                  | Schema                                           |
+| ---- | ------------------------------------------------------------ | ------------------------------------------------ |
+| 200  | Requested identity provider                                  | [store.IdentityProvider](#storeidentityprovider) |
+| 400  | ID is not a number: %s                                       |                                                  |
+| 401  | Missing user in session \| Unauthorized                      |                                                  |
+| 404  | Identity provider not found                                  |                                                  |
+| 500  | Failed to find identity provider list \| Failed to find user |                                                  |
 
 #### PATCH
+
 ##### Summary
 
 Update an identity provider by ID
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| idpId | path | Identity Provider ID | Yes | integer |
-| body | body | Patched identity provider information | Yes | [v1.UpdateIdentityProviderRequest](#v1updateidentityproviderrequest) |
+| Name  | Located in | Description                           | Required | Schema                                                               |
+| ----- | ---------- | ------------------------------------- | -------- | -------------------------------------------------------------------- |
+| idpId | path       | Identity Provider ID                  | Yes      | integer                                                              |
+| body  | body       | Patched identity provider information | Yes      | [v1.UpdateIdentityProviderRequest](#v1updateidentityproviderrequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Patched identity provider | [store.IdentityProvider](#storeidentityprovider) |
-| 400 | ID is not a number: %s \| Malformatted patch identity provider request |  |
-| 401 | Missing user in session \| Unauthorized |  |
-| 500 | Failed to find user \| Failed to patch identity provider |  |
+| Code | Description                                                            | Schema                                           |
+| ---- | ---------------------------------------------------------------------- | ------------------------------------------------ |
+| 200  | Patched identity provider                                              | [store.IdentityProvider](#storeidentityprovider) |
+| 400  | ID is not a number: %s \| Malformatted patch identity provider request |                                                  |
+| 401  | Missing user in session \| Unauthorized                                |                                                  |
+| 500  | Failed to find user \| Failed to patch identity provider               |                                                  |
 
 ---
+
 ### /api/v1/memo
 
 #### GET
+
 ##### Summary
 
 Get a list of memos matching optional filters
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| creatorId | query | Creator ID | No | integer |
-| creatorUsername | query | Creator username | No | string |
-| rowStatus | query | Row status | No | string |
-| pinned | query | Pinned | No | boolean |
-| tag | query | Search for tag. Do not append # | No | string |
-| content | query | Search for content | No | string |
-| limit | query | Limit | No | integer |
-| offset | query | Offset | No | integer |
+| Name            | Located in | Description                     | Required | Schema  |
+| --------------- | ---------- | ------------------------------- | -------- | ------- |
+| creatorId       | query      | Creator ID                      | No       | integer |
+| creatorUsername | query      | Creator username                | No       | string  |
+| rowStatus       | query      | Row status                      | No       | string  |
+| pinned          | query      | Pinned                          | No       | boolean |
+| tag             | query      | Search for tag. Do not append # | No       | string  |
+| content         | query      | Search for content              | No       | string  |
+| limit           | query      | Limit                           | No       | integer |
+| offset          | query      | Offset                          | No       | integer |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Memo list | [ [store.Memo](#storememo) ] |
-| 400 | Missing user to find memo |  |
-| 500 | Failed to get memo display with updated ts setting value \| Failed to fetch memo list \| Failed to compose memo response |  |
+| Code | Description                                                                                                              | Schema                       |
+| ---- | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------- |
+| 200  | Memo list                                                                                                                | [ [store.Memo](#storememo) ] |
+| 400  | Missing user to find memo                                                                                                |                              |
+| 500  | Failed to get memo display with updated ts setting value \| Failed to fetch memo list \| Failed to compose memo response |                              |
 
 #### POST
+
 ##### Summary
 
 Create a memo
@@ -236,70 +251,73 @@ Create a memo
 ##### Description
 
 Visibility can be PUBLIC, PROTECTED or PRIVATE
-*You should omit fields to use their default values
+\*You should omit fields to use their default values
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| body | body | Request object. | Yes | [v1.CreateMemoRequest](#v1creatememorequest) |
+| Name | Located in | Description     | Required | Schema                                       |
+| ---- | ---------- | --------------- | -------- | -------------------------------------------- |
+| body | body       | Request object. | Yes      | [v1.CreateMemoRequest](#v1creatememorequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Stored memo | [store.Memo](#storememo) |
-| 400 | Malformatted post memo request \| Content size overflow, up to 1MB |  |
-| 401 | Missing user in session |  |
-| 404 | User not found \| Memo not found: %d |  |
-| 500 | Failed to find user setting \| Failed to unmarshal user setting value \| Failed to find system setting \| Failed to unmarshal system setting \| Failed to find user \| Failed to create memo \| Failed to create activity \| Failed to upsert memo resource \| Failed to upsert memo relation \| Failed to compose memo \| Failed to compose memo response |  |
+| Code | Description                                                                                                                                                                                                                                                                                                                                                | Schema                   |
+| ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
+| 200  | Stored memo                                                                                                                                                                                                                                                                                                                                                | [store.Memo](#storememo) |
+| 400  | Malformatted post memo request \| Content size overflow, up to 1MB                                                                                                                                                                                                                                                                                         |                          |
+| 401  | Missing user in session                                                                                                                                                                                                                                                                                                                                    |                          |
+| 404  | User not found \| Memo not found: %d                                                                                                                                                                                                                                                                                                                       |                          |
+| 500  | Failed to find user setting \| Failed to unmarshal user setting value \| Failed to find system setting \| Failed to unmarshal system setting \| Failed to find user \| Failed to create memo \| Failed to create activity \| Failed to upsert memo resource \| Failed to upsert memo relation \| Failed to compose memo \| Failed to compose memo response |                          |
 
 ### /api/v1/memo/{memoId}
 
 #### DELETE
+
 ##### Summary
 
 Delete memo by ID
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| memoId | path | Memo ID to delete | Yes | integer |
+| Name   | Located in | Description       | Required | Schema  |
+| ------ | ---------- | ----------------- | -------- | ------- |
+| memoId | path       | Memo ID to delete | Yes      | integer |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Memo deleted | boolean |
-| 400 | ID is not a number: %s |  |
-| 401 | Missing user in session \| Unauthorized |  |
-| 404 | Memo not found: %d |  |
-| 500 | Failed to find memo \| Failed to delete memo ID: %v |  |
+| Code | Description                                         | Schema  |
+| ---- | --------------------------------------------------- | ------- |
+| 200  | Memo deleted                                        | boolean |
+| 400  | ID is not a number: %s                              |         |
+| 401  | Missing user in session \| Unauthorized             |         |
+| 404  | Memo not found: %d                                  |         |
+| 500  | Failed to find memo \| Failed to delete memo ID: %v |         |
 
 #### GET
+
 ##### Summary
 
 Get memo by ID
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| memoId | path | Memo ID | Yes | integer |
+| Name   | Located in | Description | Required | Schema  |
+| ------ | ---------- | ----------- | -------- | ------- |
+| memoId | path       | Memo ID     | Yes      | integer |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Memo list | [ [store.Memo](#storememo) ] |
-| 400 | ID is not a number: %s |  |
-| 401 | Missing user in session |  |
-| 403 | this memo is private only \| this memo is protected, missing user in session |  |
-| 404 | Memo not found: %d |  |
-| 500 | Failed to find memo by ID: %v \| Failed to compose memo response |  |
+| Code | Description                                                                  | Schema                       |
+| ---- | ---------------------------------------------------------------------------- | ---------------------------- |
+| 200  | Memo list                                                                    | [ [store.Memo](#storememo) ] |
+| 400  | ID is not a number: %s                                                       |                              |
+| 401  | Missing user in session                                                      |                              |
+| 403  | this memo is private only \| this memo is protected, missing user in session |                              |
+| 404  | Memo not found: %d                                                           |                              |
+| 500  | Failed to find memo by ID: %v \| Failed to compose memo response             |                              |
 
 #### PATCH
+
 ##### Summary
 
 Update a memo
@@ -307,28 +325,29 @@ Update a memo
 ##### Description
 
 Visibility can be PUBLIC, PROTECTED or PRIVATE
-*You should omit fields to use their default values
+\*You should omit fields to use their default values
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| memoId | path | ID of memo to update | Yes | integer |
-| body | body | Patched object. | Yes | [v1.PatchMemoRequest](#v1patchmemorequest) |
+| Name   | Located in | Description          | Required | Schema                                     |
+| ------ | ---------- | -------------------- | -------- | ------------------------------------------ |
+| memoId | path       | ID of memo to update | Yes      | integer                                    |
+| body   | body       | Patched object.      | Yes      | [v1.PatchMemoRequest](#v1patchmemorequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Stored memo | [store.Memo](#storememo) |
-| 400 | ID is not a number: %s \| Malformatted patch memo request \| Content size overflow, up to 1MB |  |
-| 401 | Missing user in session \| Unauthorized |  |
-| 404 | Memo not found: %d |  |
-| 500 | Failed to find memo \| Failed to patch memo \| Failed to upsert memo resource \| Failed to delete memo resource \| Failed to compose memo response |  |
+| Code | Description                                                                                                                                        | Schema                   |
+| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
+| 200  | Stored memo                                                                                                                                        | [store.Memo](#storememo) |
+| 400  | ID is not a number: %s \| Malformatted patch memo request \| Content size overflow, up to 1MB                                                      |                          |
+| 401  | Missing user in session \| Unauthorized                                                                                                            |                          |
+| 404  | Memo not found: %d                                                                                                                                 |                          |
+| 500  | Failed to find memo \| Failed to patch memo \| Failed to upsert memo resource \| Failed to delete memo resource \| Failed to compose memo response |                          |
 
 ### /api/v1/memo/all
 
 #### GET
+
 ##### Summary
 
 Get a list of public memos matching optional filters
@@ -340,21 +359,22 @@ Authentication is optional
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| limit | query | Limit | No | integer |
-| offset | query | Offset | No | integer |
+| Name   | Located in | Description | Required | Schema  |
+| ------ | ---------- | ----------- | -------- | ------- |
+| limit  | query      | Limit       | No       | integer |
+| offset | query      | Offset      | No       | integer |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Memo list | [ [store.Memo](#storememo) ] |
-| 500 | Failed to get memo display with updated ts setting value \| Failed to fetch all memo list \| Failed to compose memo response |  |
+| Code | Description                                                                                                                  | Schema                       |
+| ---- | ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
+| 200  | Memo list                                                                                                                    | [ [store.Memo](#storememo) ] |
+| 500  | Failed to get memo display with updated ts setting value \| Failed to fetch all memo list \| Failed to compose memo response |                              |
 
 ### /api/v1/memo/stats
 
 #### GET
+
 ##### Summary
 
 Get memo stats by creator ID or username
@@ -365,67 +385,72 @@ Used to generate the heatmap
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| creatorId | query | Creator ID | No | integer |
-| creatorUsername | query | Creator username | No | string |
+| Name            | Located in | Description      | Required | Schema  |
+| --------------- | ---------- | ---------------- | -------- | ------- |
+| creatorId       | query      | Creator ID       | No       | integer |
+| creatorUsername | query      | Creator username | No       | string  |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Memo createdTs list | [ integer ] |
-| 400 | Missing user id to find memo |  |
-| 500 | Failed to get memo display with updated ts setting value \| Failed to find memo list \| Failed to compose memo response |  |
+| Code | Description                                                                                                             | Schema      |
+| ---- | ----------------------------------------------------------------------------------------------------------------------- | ----------- |
+| 200  | Memo createdTs list                                                                                                     | [ integer ] |
+| 400  | Missing user id to find memo                                                                                            |             |
+| 500  | Failed to get memo display with updated ts setting value \| Failed to find memo list \| Failed to compose memo response |             |
 
 ---
+
 ### /api/v1/memo/{memoId}/organizer
 
 #### POST
+
 ##### Summary
 
 Organize memo (pin/unpin)
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| memoId | path | ID of memo to organize | Yes | integer |
-| body | body | Memo organizer object | Yes | [v1.UpsertMemoOrganizerRequest](#v1upsertmemoorganizerrequest) |
+| Name   | Located in | Description            | Required | Schema                                                         |
+| ------ | ---------- | ---------------------- | -------- | -------------------------------------------------------------- |
+| memoId | path       | ID of memo to organize | Yes      | integer                                                        |
+| body   | body       | Memo organizer object  | Yes      | [v1.UpsertMemoOrganizerRequest](#v1upsertmemoorganizerrequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Memo information | [store.Memo](#storememo) |
-| 400 | ID is not a number: %s \| Malformatted post memo organizer request |  |
-| 401 | Missing user in session \| Unauthorized |  |
-| 404 | Memo not found: %v |  |
-| 500 | Failed to find memo \| Failed to upsert memo organizer \| Failed to find memo by ID: %v \| Failed to compose memo response |  |
+| Code | Description                                                                                                                | Schema                   |
+| ---- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
+| 200  | Memo information                                                                                                           | [store.Memo](#storememo) |
+| 400  | ID is not a number: %s \| Malformatted post memo organizer request                                                         |                          |
+| 401  | Missing user in session \| Unauthorized                                                                                    |                          |
+| 404  | Memo not found: %v                                                                                                         |                          |
+| 500  | Failed to find memo \| Failed to upsert memo organizer \| Failed to find memo by ID: %v \| Failed to compose memo response |                          |
 
 ---
+
 ### /api/v1/memo/{memoId}/relation
 
 #### GET
+
 ##### Summary
 
 Get a list of Memo Relations
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| memoId | path | ID of memo to find relations | Yes | integer |
+| Name   | Located in | Description                  | Required | Schema  |
+| ------ | ---------- | ---------------------------- | -------- | ------- |
+| memoId | path       | ID of memo to find relations | Yes      | integer |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Memo relation information list | [ [store.MemoRelation](#storememorelation) ] |
-| 400 | ID is not a number: %s |  |
-| 500 | Failed to list memo relations |  |
+| Code | Description                    | Schema                                       |
+| ---- | ------------------------------ | -------------------------------------------- |
+| 200  | Memo relation information list | [ [store.MemoRelation](#storememorelation) ] |
+| 400  | ID is not a number: %s         |                                              |
+| 500  | Failed to list memo relations  |                                              |
 
 #### POST
+
 ##### Summary
 
 Create Memo Relation
@@ -436,22 +461,23 @@ Create a relation between two memos
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| memoId | path | ID of memo to relate | Yes | integer |
-| body | body | Memo relation object | Yes | [v1.UpsertMemoRelationRequest](#v1upsertmemorelationrequest) |
+| Name   | Located in | Description          | Required | Schema                                                       |
+| ------ | ---------- | -------------------- | -------- | ------------------------------------------------------------ |
+| memoId | path       | ID of memo to relate | Yes      | integer                                                      |
+| body   | body       | Memo relation object | Yes      | [v1.UpsertMemoRelationRequest](#v1upsertmemorelationrequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Memo relation information | [store.MemoRelation](#storememorelation) |
-| 400 | ID is not a number: %s \| Malformatted post memo relation request |  |
-| 500 | Failed to upsert memo relation |  |
+| Code | Description                                                       | Schema                                   |
+| ---- | ----------------------------------------------------------------- | ---------------------------------------- |
+| 200  | Memo relation information                                         | [store.MemoRelation](#storememorelation) |
+| 400  | ID is not a number: %s \| Malformatted post memo relation request |                                          |
+| 500  | Failed to upsert memo relation                                    |                                          |
 
 ### /api/v1/memo/{memoId}/relation/{relatedMemoId}/type/{relationType}
 
 #### DELETE
+
 ##### Summary
 
 Delete a Memo Relation
@@ -462,430 +488,458 @@ Removes a relation between two memos
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| memoId | path | ID of memo to find relations | Yes | integer |
-| relatedMemoId | path | ID of memo to remove relation to | Yes | integer |
-| relationType | path | Type of relation to remove | Yes | string |
+| Name          | Located in | Description                      | Required | Schema  |
+| ------------- | ---------- | -------------------------------- | -------- | ------- |
+| memoId        | path       | ID of memo to find relations     | Yes      | integer |
+| relatedMemoId | path       | ID of memo to remove relation to | Yes      | integer |
+| relationType  | path       | Type of relation to remove       | Yes      | string  |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Memo relation deleted | boolean |
-| 400 | Memo ID is not a number: %s \| Related memo ID is not a number: %s |  |
-| 500 | Failed to delete memo relation |  |
+| Code | Description                                                        | Schema  |
+| ---- | ------------------------------------------------------------------ | ------- |
+| 200  | Memo relation deleted                                              | boolean |
+| 400  | Memo ID is not a number: %s \| Related memo ID is not a number: %s |         |
+| 500  | Failed to delete memo relation                                     |         |
 
 ---
+
 ### /api/v1/ping
 
 #### GET
+
 ##### Summary
 
 Ping the system
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | If succeed to ping the system | boolean |
+| Code | Description                   | Schema  |
+| ---- | ----------------------------- | ------- |
+| 200  | If succeed to ping the system | boolean |
 
 ### /api/v1/status
 
 #### GET
+
 ##### Summary
 
 Get system GetSystemStatus
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | System GetSystemStatus | [v1.SystemStatus](#v1systemstatus) |
-| 401 | Missing user in session \| Unauthorized |  |
-| 500 | Failed to find host user \| Failed to find system setting list \| Failed to unmarshal system setting customized profile value |  |
+| Code | Description                                                                                                                   | Schema                             |
+| ---- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
+| 200  | System GetSystemStatus                                                                                                        | [v1.SystemStatus](#v1systemstatus) |
+| 401  | Missing user in session \| Unauthorized                                                                                       |                                    |
+| 500  | Failed to find host user \| Failed to find system setting list \| Failed to unmarshal system setting customized profile value |                                    |
 
 ### /api/v1/system/vacuum
 
 #### POST
+
 ##### Summary
 
 Vacuum the database
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Database vacuumed | boolean |
-| 401 | Missing user in session \| Unauthorized |  |
-| 500 | Failed to find user \| Failed to ExecVacuum database |  |
+| Code | Description                                          | Schema  |
+| ---- | ---------------------------------------------------- | ------- |
+| 200  | Database vacuumed                                    | boolean |
+| 401  | Missing user in session \| Unauthorized              |         |
+| 500  | Failed to find user \| Failed to ExecVacuum database |         |
 
 ---
+
 ### /api/v1/resource
 
 #### GET
+
 ##### Summary
 
 Get a list of resources
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| limit | query | Limit | No | integer |
-| offset | query | Offset | No | integer |
+| Name   | Located in | Description | Required | Schema  |
+| ------ | ---------- | ----------- | -------- | ------- |
+| limit  | query      | Limit       | No       | integer |
+| offset | query      | Offset      | No       | integer |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Resource list | [ [store.Resource](#storeresource) ] |
-| 401 | Missing user in session |  |
-| 500 | Failed to fetch resource list |  |
+| Code | Description                   | Schema                               |
+| ---- | ----------------------------- | ------------------------------------ |
+| 200  | Resource list                 | [ [store.Resource](#storeresource) ] |
+| 401  | Missing user in session       |                                      |
+| 500  | Failed to fetch resource list |                                      |
 
 #### POST
+
 ##### Summary
 
 Create resource
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| body | body | Request object. | Yes | [v1.CreateResourceRequest](#v1createresourcerequest) |
+| Name | Located in | Description     | Required | Schema                                               |
+| ---- | ---------- | --------------- | -------- | ---------------------------------------------------- |
+| body | body       | Request object. | Yes      | [v1.CreateResourceRequest](#v1createresourcerequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Created resource | [store.Resource](#storeresource) |
-| 400 | Malformatted post resource request \| Invalid external link \| Invalid external link scheme \| Failed to request %s \| Failed to read %s \| Failed to read mime from %s |  |
-| 401 | Missing user in session |  |
-| 500 | Failed to save resource \| Failed to create resource \| Failed to create activity |  |
+| Code | Description                                                                                                                                                             | Schema                           |
+| ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
+| 200  | Created resource                                                                                                                                                        | [store.Resource](#storeresource) |
+| 400  | Malformatted post resource request \| Invalid external link \| Invalid external link scheme \| Failed to request %s \| Failed to read %s \| Failed to read mime from %s |                                  |
+| 401  | Missing user in session                                                                                                                                                 |                                  |
+| 500  | Failed to save resource \| Failed to create resource \| Failed to create activity                                                                                       |                                  |
 
 ### /api/v1/resource/{resourceId}
 
 #### DELETE
+
 ##### Summary
 
 Delete a resource
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| resourceId | path | Resource ID | Yes | integer |
+| Name       | Located in | Description | Required | Schema  |
+| ---------- | ---------- | ----------- | -------- | ------- |
+| resourceId | path       | Resource ID | Yes      | integer |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Resource deleted | boolean |
-| 400 | ID is not a number: %s |  |
-| 401 | Missing user in session |  |
-| 404 | Resource not found: %d |  |
-| 500 | Failed to find resource \| Failed to delete resource |  |
+| Code | Description                                          | Schema  |
+| ---- | ---------------------------------------------------- | ------- |
+| 200  | Resource deleted                                     | boolean |
+| 400  | ID is not a number: %s                               |         |
+| 401  | Missing user in session                              |         |
+| 404  | Resource not found: %d                               |         |
+| 500  | Failed to find resource \| Failed to delete resource |         |
 
 #### PATCH
+
 ##### Summary
 
 Update a resource
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| resourceId | path | Resource ID | Yes | integer |
-| patch | body | Patch resource request | Yes | [v1.UpdateResourceRequest](#v1updateresourcerequest) |
+| Name       | Located in | Description            | Required | Schema                                               |
+| ---------- | ---------- | ---------------------- | -------- | ---------------------------------------------------- |
+| resourceId | path       | Resource ID            | Yes      | integer                                              |
+| patch      | body       | Patch resource request | Yes      | [v1.UpdateResourceRequest](#v1updateresourcerequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Updated resource | [store.Resource](#storeresource) |
-| 400 | ID is not a number: %s \| Malformatted patch resource request |  |
-| 401 | Missing user in session \| Unauthorized |  |
-| 404 | Resource not found: %d |  |
-| 500 | Failed to find resource \| Failed to patch resource |  |
+| Code | Description                                                   | Schema                           |
+| ---- | ------------------------------------------------------------- | -------------------------------- |
+| 200  | Updated resource                                              | [store.Resource](#storeresource) |
+| 400  | ID is not a number: %s \| Malformatted patch resource request |                                  |
+| 401  | Missing user in session \| Unauthorized                       |                                  |
+| 404  | Resource not found: %d                                        |                                  |
+| 500  | Failed to find resource \| Failed to patch resource           |                                  |
 
 ### /api/v1/resource/blob
 
 #### POST
+
 ##### Summary
 
 Upload resource
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| file | formData | File to upload | Yes | file |
+| Name | Located in | Description    | Required | Schema |
+| ---- | ---------- | -------------- | -------- | ------ |
+| file | formData   | File to upload | Yes      | file   |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Created resource | [store.Resource](#storeresource) |
-| 400 | Upload file not found \| File size exceeds allowed limit of %d MiB \| Failed to parse upload data |  |
-| 401 | Missing user in session |  |
-| 500 | Failed to get uploading file \| Failed to open file \| Failed to save resource \| Failed to create resource \| Failed to create activity |  |
+| Code | Description                                                                                                                              | Schema                           |
+| ---- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
+| 200  | Created resource                                                                                                                         | [store.Resource](#storeresource) |
+| 400  | Upload file not found \| File size exceeds allowed limit of %d MiB \| Failed to parse upload data                                        |                                  |
+| 401  | Missing user in session                                                                                                                  |                                  |
+| 500  | Failed to get uploading file \| Failed to open file \| Failed to save resource \| Failed to create resource \| Failed to create activity |                                  |
 
 ### /o/r/{resourceId}
 
 #### GET
+
 ##### Summary
 
 Stream a resource
 
 ##### Description
 
-*Swagger UI may have problems displaying other file types than images
+\*Swagger UI may have problems displaying other file types than images
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| resourceId | path | Resource ID | Yes | integer |
-| thumbnail | query | Thumbnail | No | integer |
+| Name       | Located in | Description | Required | Schema  |
+| ---------- | ---------- | ----------- | -------- | ------- |
+| resourceId | path       | Resource ID | Yes      | integer |
+| thumbnail  | query      | Thumbnail   | No       | integer |
 
 ##### Responses
 
-| Code | Description |
-| ---- | ----------- |
-| 200 | Requested resource |
-| 400 | ID is not a number: %s \| Failed to get resource visibility |
-| 401 | Resource visibility not match |
-| 404 | Resource not found: %d |
-| 500 | Failed to find resource by ID: %v \| Failed to open the local resource: %s \| Failed to read the local resource: %s |
+| Code | Description                                                                                                         |
+| ---- | ------------------------------------------------------------------------------------------------------------------- |
+| 200  | Requested resource                                                                                                  |
+| 400  | ID is not a number: %s \| Failed to get resource visibility                                                         |
+| 401  | Resource visibility not match                                                                                       |
+| 404  | Resource not found: %d                                                                                              |
+| 500  | Failed to find resource by ID: %v \| Failed to open the local resource: %s \| Failed to read the local resource: %s |
 
 ---
+
 ### /api/v1/storage
 
 #### GET
+
 ##### Summary
 
 Get a list of storages
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | List of storages | [ [store.Storage](#storestorage) ] |
-| 401 | Missing user in session \| Unauthorized |  |
-| 500 | Failed to find user \| Failed to convert storage |  |
+| Code | Description                                      | Schema                             |
+| ---- | ------------------------------------------------ | ---------------------------------- |
+| 200  | List of storages                                 | [ [store.Storage](#storestorage) ] |
+| 401  | Missing user in session \| Unauthorized          |                                    |
+| 500  | Failed to find user \| Failed to convert storage |                                    |
 
 #### POST
+
 ##### Summary
 
 Create storage
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| body | body | Request object. | Yes | [v1.CreateStorageRequest](#v1createstoragerequest) |
+| Name | Located in | Description     | Required | Schema                                             |
+| ---- | ---------- | --------------- | -------- | -------------------------------------------------- |
+| body | body       | Request object. | Yes      | [v1.CreateStorageRequest](#v1createstoragerequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Created storage | [store.Storage](#storestorage) |
-| 400 | Malformatted post storage request |  |
-| 401 | Missing user in session |  |
-| 500 | Failed to find user \| Failed to create storage \| Failed to convert storage |  |
+| Code | Description                                                                  | Schema                         |
+| ---- | ---------------------------------------------------------------------------- | ------------------------------ |
+| 200  | Created storage                                                              | [store.Storage](#storestorage) |
+| 400  | Malformatted post storage request                                            |                                |
+| 401  | Missing user in session                                                      |                                |
+| 500  | Failed to find user \| Failed to create storage \| Failed to convert storage |                                |
 
 ### /api/v1/storage/{storageId}
 
 #### DELETE
+
 ##### Summary
 
 Delete a storage
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| storageId | path | Storage ID | Yes | integer |
+| Name      | Located in | Description | Required | Schema  |
+| --------- | ---------- | ----------- | -------- | ------- |
+| storageId | path       | Storage ID  | Yes      | integer |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Storage deleted | boolean |
-| 400 | ID is not a number: %s \| Storage service %d is using |  |
-| 401 | Missing user in session \| Unauthorized |  |
-| 500 | Failed to find user \| Failed to find storage \| Failed to unmarshal storage service id \| Failed to delete storage |  |
+| Code | Description                                                                                                         | Schema  |
+| ---- | ------------------------------------------------------------------------------------------------------------------- | ------- |
+| 200  | Storage deleted                                                                                                     | boolean |
+| 400  | ID is not a number: %s \| Storage service %d is using                                                               |         |
+| 401  | Missing user in session \| Unauthorized                                                                             |         |
+| 500  | Failed to find user \| Failed to find storage \| Failed to unmarshal storage service id \| Failed to delete storage |         |
 
 #### PATCH
+
 ##### Summary
 
 Update a storage
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| storageId | path | Storage ID | Yes | integer |
-| patch | body | Patch request | Yes | [v1.UpdateStorageRequest](#v1updatestoragerequest) |
+| Name      | Located in | Description   | Required | Schema                                             |
+| --------- | ---------- | ------------- | -------- | -------------------------------------------------- |
+| storageId | path       | Storage ID    | Yes      | integer                                            |
+| patch     | body       | Patch request | Yes      | [v1.UpdateStorageRequest](#v1updatestoragerequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Updated resource | [store.Storage](#storestorage) |
-| 400 | ID is not a number: %s \| Malformatted patch storage request \| Malformatted post storage request |  |
-| 401 | Missing user in session \| Unauthorized |  |
-| 500 | Failed to find user \| Failed to patch storage \| Failed to convert storage |  |
+| Code | Description                                                                                       | Schema                         |
+| ---- | ------------------------------------------------------------------------------------------------- | ------------------------------ |
+| 200  | Updated resource                                                                                  | [store.Storage](#storestorage) |
+| 400  | ID is not a number: %s \| Malformatted patch storage request \| Malformatted post storage request |                                |
+| 401  | Missing user in session \| Unauthorized                                                           |                                |
+| 500  | Failed to find user \| Failed to patch storage \| Failed to convert storage                       |                                |
 
 ---
+
 ### /api/v1/system/setting
 
 #### GET
+
 ##### Summary
 
 Get a list of system settings
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | System setting list | [ [v1.SystemSetting](#v1systemsetting) ] |
-| 401 | Missing user in session \| Unauthorized |  |
-| 500 | Failed to find user \| Failed to find system setting list |  |
+| Code | Description                                               | Schema                                   |
+| ---- | --------------------------------------------------------- | ---------------------------------------- |
+| 200  | System setting list                                       | [ [v1.SystemSetting](#v1systemsetting) ] |
+| 401  | Missing user in session \| Unauthorized                   |                                          |
+| 500  | Failed to find user \| Failed to find system setting list |                                          |
 
 #### POST
+
 ##### Summary
 
 Create system setting
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| body | body | Request object. | Yes | [v1.UpsertSystemSettingRequest](#v1upsertsystemsettingrequest) |
+| Name | Located in | Description     | Required | Schema                                                         |
+| ---- | ---------- | --------------- | -------- | -------------------------------------------------------------- |
+| body | body       | Request object. | Yes      | [v1.UpsertSystemSettingRequest](#v1upsertsystemsettingrequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Created system setting | [store.SystemSetting](#storesystemsetting) |
-| 400 | Malformatted post system setting request \| invalid system setting |  |
-| 401 | Missing user in session \| Unauthorized |  |
-| 403 | Cannot disable passwords if no SSO identity provider is configured. |  |
-| 500 | Failed to find user \| Failed to upsert system setting |  |
+| Code | Description                                                         | Schema                                     |
+| ---- | ------------------------------------------------------------------- | ------------------------------------------ |
+| 200  | Created system setting                                              | [store.SystemSetting](#storesystemsetting) |
+| 400  | Malformatted post system setting request \| invalid system setting  |                                            |
+| 401  | Missing user in session \| Unauthorized                             |                                            |
+| 403  | Cannot disable passwords if no SSO identity provider is configured. |                                            |
+| 500  | Failed to find user \| Failed to upsert system setting              |                                            |
 
 ---
+
 ### /api/v1/tag
 
 #### GET
+
 ##### Summary
 
 Get a list of tags
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Tag list | [ string ] |
-| 400 | Missing user id to find tag |  |
-| 500 | Failed to find tag list |  |
+| Code | Description                 | Schema     |
+| ---- | --------------------------- | ---------- |
+| 200  | Tag list                    | [ string ] |
+| 400  | Missing user id to find tag |            |
+| 500  | Failed to find tag list     |            |
 
 #### POST
+
 ##### Summary
 
 Create a tag
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| body | body | Request object. | Yes | [v1.UpsertTagRequest](#v1upserttagrequest) |
+| Name | Located in | Description     | Required | Schema                                     |
+| ---- | ---------- | --------------- | -------- | ------------------------------------------ |
+| body | body       | Request object. | Yes      | [v1.UpsertTagRequest](#v1upserttagrequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Created tag name | string |
-| 400 | Malformatted post tag request \| Tag name shouldn't be empty |  |
-| 401 | Missing user in session |  |
-| 500 | Failed to upsert tag \| Failed to create activity |  |
+| Code | Description                                                  | Schema |
+| ---- | ------------------------------------------------------------ | ------ |
+| 200  | Created tag name                                             | string |
+| 400  | Malformatted post tag request \| Tag name shouldn't be empty |        |
+| 401  | Missing user in session                                      |        |
+| 500  | Failed to upsert tag \| Failed to create activity            |        |
 
 ### /api/v1/tag/delete
 
 #### POST
+
 ##### Summary
 
 Delete a tag
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| body | body | Request object. | Yes | [v1.DeleteTagRequest](#v1deletetagrequest) |
+| Name | Located in | Description     | Required | Schema                                     |
+| ---- | ---------- | --------------- | -------- | ------------------------------------------ |
+| body | body       | Request object. | Yes      | [v1.DeleteTagRequest](#v1deletetagrequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Tag deleted | boolean |
-| 400 | Malformatted post tag request \| Tag name shouldn't be empty |  |
-| 401 | Missing user in session |  |
-| 500 | Failed to delete tag name: %v |  |
+| Code | Description                                                  | Schema  |
+| ---- | ------------------------------------------------------------ | ------- |
+| 200  | Tag deleted                                                  | boolean |
+| 400  | Malformatted post tag request \| Tag name shouldn't be empty |         |
+| 401  | Missing user in session                                      |         |
+| 500  | Failed to delete tag name: %v                                |         |
 
 ### /api/v1/tag/suggestion
 
 #### GET
+
 ##### Summary
 
 Get a list of tags suggested from other memos contents
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Tag list | [ string ] |
-| 400 | Missing user session |  |
-| 500 | Failed to find memo list \| Failed to find tag list |  |
+| Code | Description                                         | Schema     |
+| ---- | --------------------------------------------------- | ---------- |
+| 200  | Tag list                                            | [ string ] |
+| 400  | Missing user session                                |            |
+| 500  | Failed to find memo list \| Failed to find tag list |            |
 
 ---
+
 ### /api/v1/user
 
 #### GET
+
 ##### Summary
 
 Get a list of users
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | User list | [ [store.User](#storeuser) ] |
-| 500 | Failed to fetch user list |  |
+| Code | Description               | Schema                       |
+| ---- | ------------------------- | ---------------------------- |
+| 200  | User list                 | [ [store.User](#storeuser) ] |
+| 500  | Failed to fetch user list |                              |
 
 #### POST
+
 ##### Summary
 
 Create a user
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| body | body | Request object | Yes | [v1.CreateUserRequest](#v1createuserrequest) |
+| Name | Located in | Description    | Required | Schema                                       |
+| ---- | ---------- | -------------- | -------- | -------------------------------------------- |
+| body | body       | Request object | Yes      | [v1.CreateUserRequest](#v1createuserrequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Created user | [store.User](#storeuser) |
-| 400 | Malformatted post user request \| Invalid user create format |  |
-| 401 | Missing auth session \| Unauthorized to create user |  |
-| 403 | Could not create host user |  |
-| 500 | Failed to find user by id \| Failed to generate password hash \| Failed to create user \| Failed to create activity |  |
+| Code | Description                                                                                                         | Schema                   |
+| ---- | ------------------------------------------------------------------------------------------------------------------- | ------------------------ |
+| 200  | Created user                                                                                                        | [store.User](#storeuser) |
+| 400  | Malformatted post user request \| Invalid user create format                                                        |                          |
+| 401  | Missing auth session \| Unauthorized to create user                                                                 |                          |
+| 403  | Could not create host user                                                                                          |                          |
+| 500  | Failed to find user by id \| Failed to generate password hash \| Failed to create user \| Failed to create activity |                          |
 
 ### /api/v1/user/{id}
 
 #### DELETE
+
 ##### Summary
 
 Delete a user
@@ -894,675 +948,660 @@ Delete a user
 
 | Name | Located in | Description | Required | Schema |
 | ---- | ---------- | ----------- | -------- | ------ |
-| id | path | User ID | Yes | string |
+| id   | path       | User ID     | Yes      | string |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | User deleted | boolean |
-| 400 | ID is not a number: %s \| Current session user not found with ID: %d |  |
-| 401 | Missing user in session |  |
-| 403 | Unauthorized to delete user |  |
-| 500 | Failed to find user \| Failed to delete user |  |
+| Code | Description                                                          | Schema  |
+| ---- | -------------------------------------------------------------------- | ------- |
+| 200  | User deleted                                                         | boolean |
+| 400  | ID is not a number: %s \| Current session user not found with ID: %d |         |
+| 401  | Missing user in session                                              |         |
+| 403  | Unauthorized to delete user                                          |         |
+| 500  | Failed to find user \| Failed to delete user                         |         |
 
 #### GET
+
 ##### Summary
 
 Get user by id
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| id | path | User ID | Yes | integer |
+| Name | Located in | Description | Required | Schema  |
+| ---- | ---------- | ----------- | -------- | ------- |
+| id   | path       | User ID     | Yes      | integer |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Requested user | [store.User](#storeuser) |
-| 400 | Malformatted user id |  |
-| 404 | User not found |  |
-| 500 | Failed to find user |  |
+| Code | Description          | Schema                   |
+| ---- | -------------------- | ------------------------ |
+| 200  | Requested user       | [store.User](#storeuser) |
+| 400  | Malformatted user id |                          |
+| 404  | User not found       |                          |
+| 500  | Failed to find user  |                          |
 
 #### PATCH
+
 ##### Summary
 
 Update a user
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| id | path | User ID | Yes | string |
-| patch | body | Patch request | Yes | [v1.UpdateUserRequest](#v1updateuserrequest) |
+| Name  | Located in | Description   | Required | Schema                                       |
+| ----- | ---------- | ------------- | -------- | -------------------------------------------- |
+| id    | path       | User ID       | Yes      | string                                       |
+| patch | body       | Patch request | Yes      | [v1.UpdateUserRequest](#v1updateuserrequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Updated user | [store.User](#storeuser) |
-| 400 | ID is not a number: %s \| Current session user not found with ID: %d \| Malformatted patch user request \| Invalid update user request |  |
-| 401 | Missing user in session |  |
-| 403 | Unauthorized to update user |  |
-| 500 | Failed to find user \| Failed to generate password hash \| Failed to patch user \| Failed to find userSettingList |  |
+| Code | Description                                                                                                                            | Schema                   |
+| ---- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
+| 200  | Updated user                                                                                                                           | [store.User](#storeuser) |
+| 400  | ID is not a number: %s \| Current session user not found with ID: %d \| Malformatted patch user request \| Invalid update user request |                          |
+| 401  | Missing user in session                                                                                                                |                          |
+| 403  | Unauthorized to update user                                                                                                            |                          |
+| 500  | Failed to find user \| Failed to generate password hash \| Failed to patch user \| Failed to find userSettingList                      |                          |
 
 ### /api/v1/user/me
 
 #### GET
+
 ##### Summary
 
 Get current user
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Current user | [store.User](#storeuser) |
-| 401 | Missing auth session |  |
-| 500 | Failed to find user \| Failed to find userSettingList |  |
+| Code | Description                                           | Schema                   |
+| ---- | ----------------------------------------------------- | ------------------------ |
+| 200  | Current user                                          | [store.User](#storeuser) |
+| 401  | Missing auth session                                  |                          |
+| 500  | Failed to find user \| Failed to find userSettingList |                          |
 
 ### /api/v1/user/name/{username}
 
 #### GET
+
 ##### Summary
 
 Get user by username
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| username | path | Username | Yes | string |
+| Name     | Located in | Description | Required | Schema |
+| -------- | ---------- | ----------- | -------- | ------ |
+| username | path       | Username    | Yes      | string |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Requested user | [store.User](#storeuser) |
-| 404 | User not found |  |
-| 500 | Failed to find user |  |
+| Code | Description         | Schema                   |
+| ---- | ------------------- | ------------------------ |
+| 200  | Requested user      | [store.User](#storeuser) |
+| 404  | User not found      |                          |
+| 500  | Failed to find user |                          |
 
 ---
+
 ### /api/v1/user/setting
 
 #### POST
+
 ##### Summary
 
 Upsert user setting
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| body | body | Request object. | Yes | [v1.UpsertUserSettingRequest](#v1upsertusersettingrequest) |
+| Name | Located in | Description     | Required | Schema                                                     |
+| ---- | ---------- | --------------- | -------- | ---------------------------------------------------------- |
+| body | body       | Request object. | Yes      | [v1.UpsertUserSettingRequest](#v1upsertusersettingrequest) |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Created user setting | [github_com_usememos_memos_store.UserSetting](#github_com_usememos_memos_storeusersetting) |
-| 400 | Malformatted post user setting upsert request \| Invalid user setting format |  |
-| 401 | Missing auth session |  |
-| 500 | Failed to upsert user setting |  |
+| Code | Description                                                                  | Schema                                                                                     |
+| ---- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
+| 200  | Created user setting                                                         | [github_com_usememos_memos_store.UserSetting](#github_com_usememos_memos_storeusersetting) |
+| 400  | Malformatted post user setting upsert request \| Invalid user setting format |                                                                                            |
+| 401  | Missing auth session                                                         |                                                                                            |
+| 500  | Failed to upsert user setting                                                |                                                                                            |
 
 ---
+
 ### /explore/rss.xml
 
 #### GET
+
 ##### Summary
 
 Get RSS
 
 ##### Responses
 
-| Code | Description |
-| ---- | ----------- |
-| 200 | RSS |
-| 500 | Failed to get system customized profile \| Failed to find memo list \| Failed to generate rss |
+| Code | Description                                                                                   |
+| ---- | --------------------------------------------------------------------------------------------- |
+| 200  | RSS                                                                                           |
+| 500  | Failed to get system customized profile \| Failed to find memo list \| Failed to generate rss |
 
 ### /u/{id}/rss.xml
 
 #### GET
+
 ##### Summary
 
 Get RSS for a user
 
 ##### Parameters
 
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| id | path | User ID | Yes | integer |
+| Name | Located in | Description | Required | Schema  |
+| ---- | ---------- | ----------- | -------- | ------- |
+| id   | path       | User ID     | Yes      | integer |
 
 ##### Responses
 
-| Code | Description |
-| ---- | ----------- |
-| 200 | RSS |
-| 400 | User id is not a number |
-| 500 | Failed to get system customized profile \| Failed to find memo list \| Failed to generate rss |
+| Code | Description                                                                                   |
+| ---- | --------------------------------------------------------------------------------------------- |
+| 200  | RSS                                                                                           |
+| 400  | User id is not a number                                                                       |
+| 500  | Failed to get system customized profile \| Failed to find memo list \| Failed to generate rss |
 
 ---
+
 ### /o/get/GetImage
 
 #### GET
-##### Summary
-
-Get GetImage from URL
-
-##### Parameters
-
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| url | query | Image url | Yes | string |
 
-##### Responses
-
-| Code | Description |
-| ---- | ----------- |
-| 200 | Image |
-| 400 | Missing GetImage url \| Wrong url \| Failed to get GetImage url: %s |
-| 500 | Failed to write GetImage blob |
-
-### /o/get/GetWebsiteMetadata
-
-#### GET
 ##### Summary
 
-Get website metadata
+Get GetImage from URL
 
 ##### Parameters
 
 | Name | Located in | Description | Required | Schema |
 | ---- | ---------- | ----------- | -------- | ------ |
-| url | query | Website URL | Yes | string |
+| url  | query      | Image url   | Yes      | string |
 
 ##### Responses
 
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Extracted metadata | [getter.HTMLMeta](#getterhtmlmeta) |
-| 400 | Missing website url \| Wrong url |  |
-| 406 | Failed to get website meta with url: %s |  |
+| Code | Description                                                         |
+| ---- | ------------------------------------------------------------------- |
+| 200  | Image                                                               |
+| 400  | Missing GetImage url \| Wrong url \| Failed to get GetImage url: %s |
+| 500  | Failed to write GetImage blob                                       |
 
 ---
-### Models
 
-#### getter.HTMLMeta
-
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| description | string |  | No |
-| image | string |  | No |
-| title | string |  | No |
+### Models
 
 #### github_com_usememos_memos_store.UserSetting
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| key | string |  | No |
-| userID | integer |  | No |
-| value | string |  | No |
+| Name   | Type    | Description | Required |
+| ------ | ------- | ----------- | -------- |
+| key    | string  |             | No       |
+| userID | integer |             | No       |
+| value  | string  |             | No       |
 
 #### profile.Profile
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| mode | string | Mode can be "prod" or "dev" or "demo" | No |
-| version | string | Version is the current version of server | No |
+| Name    | Type   | Description                                   | Required |
+| ------- | ------ | --------------------------------------------- | -------- |
+| driver  | string | Driver is the database driver sqlite, mysql   | No       |
+| dsn     | string | DSN points to where Memos stores its own data | No       |
+| mode    | string | Mode can be "prod" or "dev" or "demo"         | No       |
+| version | string | Version is the current version of server      | No       |
 
 #### store.FieldMapping
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| displayName | string |  | No |
-| email | string |  | No |
-| identifier | string |  | No |
+| Name        | Type   | Description | Required |
+| ----------- | ------ | ----------- | -------- |
+| displayName | string |             | No       |
+| email       | string |             | No       |
+| identifier  | string |             | No       |
 
 #### store.IdentityProvider
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| config | [store.IdentityProviderConfig](#storeidentityproviderconfig) |  | No |
-| id | integer |  | No |
-| identifierFilter | string |  | No |
-| name | string |  | No |
-| type | [store.IdentityProviderType](#storeidentityprovidertype) |  | No |
+| Name             | Type                                                         | Description | Required |
+| ---------------- | ------------------------------------------------------------ | ----------- | -------- |
+| config           | [store.IdentityProviderConfig](#storeidentityproviderconfig) |             | No       |
+| id               | integer                                                      |             | No       |
+| identifierFilter | string                                                       |             | No       |
+| name             | string                                                       |             | No       |
+| type             | [store.IdentityProviderType](#storeidentityprovidertype)     |             | No       |
 
 #### store.IdentityProviderConfig
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| oauth2Config | [store.IdentityProviderOAuth2Config](#storeidentityprovideroauth2config) |  | No |
+| Name         | Type                                                                     | Description | Required |
+| ------------ | ------------------------------------------------------------------------ | ----------- | -------- |
+| oauth2Config | [store.IdentityProviderOAuth2Config](#storeidentityprovideroauth2config) |             | No       |
 
 #### store.IdentityProviderOAuth2Config
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| authUrl | string |  | No |
-| clientId | string |  | No |
-| clientSecret | string |  | No |
-| fieldMapping | [store.FieldMapping](#storefieldmapping) |  | No |
-| scopes | [ string ] |  | No |
-| tokenUrl | string |  | No |
-| userInfoUrl | string |  | No |
+| Name         | Type                                     | Description | Required |
+| ------------ | ---------------------------------------- | ----------- | -------- |
+| authUrl      | string                                   |             | No       |
+| clientId     | string                                   |             | No       |
+| clientSecret | string                                   |             | No       |
+| fieldMapping | [store.FieldMapping](#storefieldmapping) |             | No       |
+| scopes       | [ string ]                               |             | No       |
+| tokenUrl     | string                                   |             | No       |
+| userInfoUrl  | string                                   |             | No       |
 
 #### store.IdentityProviderType
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| store.IdentityProviderType | string |  |  |
+| Name                       | Type   | Description | Required |
+| -------------------------- | ------ | ----------- | -------- |
+| store.IdentityProviderType | string |             |          |
 
 #### store.Memo
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| content | string | Domain specific fields | No |
-| createdTs | integer |  | No |
-| creatorID | integer |  | No |
-| id | integer |  | No |
-| pinned | boolean | Composed fields | No |
-| relationList | [ [store.MemoRelation](#storememorelation) ] |  | No |
-| resourceIDList | [ integer ] |  | No |
-| rowStatus | [store.RowStatus](#storerowstatus) | Standard fields | No |
-| updatedTs | integer |  | No |
-| visibility | [store.Visibility](#storevisibility) |  | No |
+| Name           | Type                                         | Description                                                                                                                                                  | Required |
+| -------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
+| content        | string                                       | Domain specific fields                                                                                                                                       | No       |
+| createdTs      | integer                                      |                                                                                                                                                              | No       |
+| creatorID      | integer                                      |                                                                                                                                                              | No       |
+| id             | integer                                      |                                                                                                                                                              | No       |
+| parentID       | integer                                      | Composed fields For those comment memos, the parent ID is the memo ID of the memo being commented. If the parent ID is nil, then this memo is not a comment. | No       |
+| pinned         | boolean                                      |                                                                                                                                                              | No       |
+| relationList   | [ [store.MemoRelation](#storememorelation) ] |                                                                                                                                                              | No       |
+| resourceIDList | [ integer ]                                  |                                                                                                                                                              | No       |
+| rowStatus      | [store.RowStatus](#storerowstatus)           | Standard fields                                                                                                                                              | No       |
+| updatedTs      | integer                                      |                                                                                                                                                              | No       |
+| visibility     | [store.Visibility](#storevisibility)         |                                                                                                                                                              | No       |
 
 #### store.MemoRelation
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| memoID | integer |  | No |
-| relatedMemoID | integer |  | No |
-| type | [store.MemoRelationType](#storememorelationtype) |  | No |
+| Name          | Type                                             | Description | Required |
+| ------------- | ------------------------------------------------ | ----------- | -------- |
+| memoID        | integer                                          |             | No       |
+| relatedMemoID | integer                                          |             | No       |
+| type          | [store.MemoRelationType](#storememorelationtype) |             | No       |
 
 #### store.MemoRelationType
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| store.MemoRelationType | string |  |  |
+| Name                   | Type   | Description | Required |
+| ---------------------- | ------ | ----------- | -------- |
+| store.MemoRelationType | string |             |          |
 
 #### store.Resource
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| blob | [ integer ] |  | No |
-| createdTs | integer |  | No |
-| creatorID | integer | Standard fields | No |
-| externalLink | string |  | No |
-| filename | string | Domain specific fields | No |
-| id | integer |  | No |
-| internalPath | string |  | No |
-| memoID | integer |  | No |
-| size | integer |  | No |
-| type | string |  | No |
-| updatedTs | integer |  | No |
+| Name         | Type        | Description            | Required |
+| ------------ | ----------- | ---------------------- | -------- |
+| blob         | [ integer ] |                        | No       |
+| createdTs    | integer     |                        | No       |
+| creatorID    | integer     | Standard fields        | No       |
+| externalLink | string      |                        | No       |
+| filename     | string      | Domain specific fields | No       |
+| id           | integer     |                        | No       |
+| internalPath | string      |                        | No       |
+| memoID       | integer     |                        | No       |
+| size         | integer     |                        | No       |
+| type         | string      |                        | No       |
+| updatedTs    | integer     |                        | No       |
 
 #### store.Role
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| store.Role | string |  |  |
+| Name       | Type   | Description | Required |
+| ---------- | ------ | ----------- | -------- |
+| store.Role | string |             |          |
 
 #### store.RowStatus
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| store.RowStatus | string |  |  |
+| Name            | Type   | Description | Required |
+| --------------- | ------ | ----------- | -------- |
+| store.RowStatus | string |             |          |
 
 #### store.Storage
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| config | string |  | No |
-| id | integer |  | No |
-| name | string |  | No |
-| type | string |  | No |
+| Name   | Type    | Description | Required |
+| ------ | ------- | ----------- | -------- |
+| config | string  |             | No       |
+| id     | integer |             | No       |
+| name   | string  |             | No       |
+| type   | string  |             | No       |
 
 #### store.SystemSetting
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| description | string |  | No |
-| name | string |  | No |
-| value | string |  | No |
+| Name        | Type   | Description | Required |
+| ----------- | ------ | ----------- | -------- |
+| description | string |             | No       |
+| name        | string |             | No       |
+| value       | string |             | No       |
 
 #### store.User
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| avatarURL | string |  | No |
-| createdTs | integer |  | No |
-| email | string |  | No |
-| id | integer |  | No |
-| nickname | string |  | No |
-| passwordHash | string |  | No |
-| role | [store.Role](#storerole) |  | No |
-| rowStatus | [store.RowStatus](#storerowstatus) | Standard fields | No |
-| updatedTs | integer |  | No |
-| username | string | Domain specific fields | No |
+| Name         | Type                               | Description            | Required |
+| ------------ | ---------------------------------- | ---------------------- | -------- |
+| avatarURL    | string                             |                        | No       |
+| createdTs    | integer                            |                        | No       |
+| email        | string                             |                        | No       |
+| id           | integer                            |                        | No       |
+| nickname     | string                             |                        | No       |
+| passwordHash | string                             |                        | No       |
+| role         | [store.Role](#storerole)           |                        | No       |
+| rowStatus    | [store.RowStatus](#storerowstatus) | Standard fields        | No       |
+| updatedTs    | integer                            |                        | No       |
+| username     | string                             | Domain specific fields | No       |
 
 #### store.Visibility
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| store.Visibility | string |  |  |
+| Name             | Type   | Description | Required |
+| ---------------- | ------ | ----------- | -------- |
+| store.Visibility | string |             |          |
 
 #### v1.CreateIdentityProviderRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| config | [v1.IdentityProviderConfig](#v1identityproviderconfig) |  | No |
-| identifierFilter | string |  | No |
-| name | string |  | No |
-| type | [v1.IdentityProviderType](#v1identityprovidertype) |  | No |
+| Name             | Type                                                   | Description | Required |
+| ---------------- | ------------------------------------------------------ | ----------- | -------- |
+| config           | [v1.IdentityProviderConfig](#v1identityproviderconfig) |             | No       |
+| identifierFilter | string                                                 |             | No       |
+| name             | string                                                 |             | No       |
+| type             | [v1.IdentityProviderType](#v1identityprovidertype)     |             | No       |
 
 #### v1.CreateMemoRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| content | string |  | No |
-| createdTs | integer |  | No |
-| relationList | [ [v1.UpsertMemoRelationRequest](#v1upsertmemorelationrequest) ] |  | No |
-| resourceIdList | [ integer ] | Related fields | No |
-| visibility | [v1.Visibility](#v1visibility) | Domain specific fields | No |
+| Name           | Type                                                             | Description            | Required |
+| -------------- | ---------------------------------------------------------------- | ---------------------- | -------- |
+| content        | string                                                           |                        | No       |
+| createdTs      | integer                                                          |                        | No       |
+| relationList   | [ [v1.UpsertMemoRelationRequest](#v1upsertmemorelationrequest) ] |                        | No       |
+| resourceIdList | [ integer ]                                                      | Related fields         | No       |
+| visibility     | [v1.Visibility](#v1visibility)                                   | Domain specific fields | No       |
 
 #### v1.CreateResourceRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| externalLink | string |  | No |
-| filename | string |  | No |
-| internalPath | string |  | No |
-| type | string |  | No |
+| Name         | Type   | Description | Required |
+| ------------ | ------ | ----------- | -------- |
+| externalLink | string |             | No       |
+| filename     | string |             | No       |
+| type         | string |             | No       |
 
 #### v1.CreateStorageRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| config | [v1.StorageConfig](#v1storageconfig) |  | No |
-| name | string |  | No |
-| type | [v1.StorageType](#v1storagetype) |  | No |
+| Name   | Type                                 | Description | Required |
+| ------ | ------------------------------------ | ----------- | -------- |
+| config | [v1.StorageConfig](#v1storageconfig) |             | No       |
+| name   | string                               |             | No       |
+| type   | [v1.StorageType](#v1storagetype)     |             | No       |
 
 #### v1.CreateUserRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| email | string |  | No |
-| nickname | string |  | No |
-| password | string |  | No |
-| role | [v1.Role](#v1role) |  | No |
-| username | string |  | No |
+| Name     | Type               | Description | Required |
+| -------- | ------------------ | ----------- | -------- |
+| email    | string             |             | No       |
+| nickname | string             |             | No       |
+| password | string             |             | No       |
+| role     | [v1.Role](#v1role) |             | No       |
+| username | string             |             | No       |
 
 #### v1.CustomizedProfile
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| appearance | string | Appearance is the server default appearance. | No |
-| description | string | Description is the server description. | No |
-| externalUrl | string | ExternalURL is the external url of server. e.g. <https://usermemos.com> | No |
-| locale | string | Locale is the server default locale. | No |
-| logoUrl | string | LogoURL is the url of logo image. | No |
-| name | string | Name is the server name, default is `memos` | No |
+| Name        | Type   | Description                                                             | Required |
+| ----------- | ------ | ----------------------------------------------------------------------- | -------- |
+| appearance  | string | Appearance is the server default appearance.                            | No       |
+| description | string | Description is the server description.                                  | No       |
+| externalUrl | string | ExternalURL is the external url of server. e.g. <https://usermemos.com> | No       |
+| locale      | string | Locale is the server default locale.                                    | No       |
+| logoUrl     | string | LogoURL is the url of logo image.                                       | No       |
+| name        | string | Name is the server name, default is `memos`                             | No       |
 
 #### v1.DeleteTagRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| name | string |  | No |
+| Name | Type   | Description | Required |
+| ---- | ------ | ----------- | -------- |
+| name | string |             | No       |
 
 #### v1.FieldMapping
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| displayName | string |  | No |
-| email | string |  | No |
-| identifier | string |  | No |
+| Name        | Type   | Description | Required |
+| ----------- | ------ | ----------- | -------- |
+| displayName | string |             | No       |
+| email       | string |             | No       |
+| identifier  | string |             | No       |
 
 #### v1.IdentityProvider
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| config | [v1.IdentityProviderConfig](#v1identityproviderconfig) |  | No |
-| id | integer |  | No |
-| identifierFilter | string |  | No |
-| name | string |  | No |
-| type | [v1.IdentityProviderType](#v1identityprovidertype) |  | No |
+| Name             | Type                                                   | Description | Required |
+| ---------------- | ------------------------------------------------------ | ----------- | -------- |
+| config           | [v1.IdentityProviderConfig](#v1identityproviderconfig) |             | No       |
+| id               | integer                                                |             | No       |
+| identifierFilter | string                                                 |             | No       |
+| name             | string                                                 |             | No       |
+| type             | [v1.IdentityProviderType](#v1identityprovidertype)     |             | No       |
 
 #### v1.IdentityProviderConfig
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| oauth2Config | [v1.IdentityProviderOAuth2Config](#v1identityprovideroauth2config) |  | No |
+| Name         | Type                                                               | Description | Required |
+| ------------ | ------------------------------------------------------------------ | ----------- | -------- |
+| oauth2Config | [v1.IdentityProviderOAuth2Config](#v1identityprovideroauth2config) |             | No       |
 
 #### v1.IdentityProviderOAuth2Config
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| authUrl | string |  | No |
-| clientId | string |  | No |
-| clientSecret | string |  | No |
-| fieldMapping | [v1.FieldMapping](#v1fieldmapping) |  | No |
-| scopes | [ string ] |  | No |
-| tokenUrl | string |  | No |
-| userInfoUrl | string |  | No |
+| Name         | Type                               | Description | Required |
+| ------------ | ---------------------------------- | ----------- | -------- |
+| authUrl      | string                             |             | No       |
+| clientId     | string                             |             | No       |
+| clientSecret | string                             |             | No       |
+| fieldMapping | [v1.FieldMapping](#v1fieldmapping) |             | No       |
+| scopes       | [ string ]                         |             | No       |
+| tokenUrl     | string                             |             | No       |
+| userInfoUrl  | string                             |             | No       |
 
 #### v1.IdentityProviderType
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| v1.IdentityProviderType | string |  |  |
+| Name                    | Type   | Description | Required |
+| ----------------------- | ------ | ----------- | -------- |
+| v1.IdentityProviderType | string |             |          |
 
 #### v1.MemoRelationType
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| v1.MemoRelationType | string |  |  |
+| Name                | Type   | Description | Required |
+| ------------------- | ------ | ----------- | -------- |
+| v1.MemoRelationType | string |             |          |
 
 #### v1.PatchMemoRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| content | string | Domain specific fields | No |
-| createdTs | integer | Standard fields | No |
-| relationList | [ [v1.UpsertMemoRelationRequest](#v1upsertmemorelationrequest) ] |  | No |
-| resourceIdList | [ integer ] | Related fields | No |
-| rowStatus | [v1.RowStatus](#v1rowstatus) |  | No |
-| updatedTs | integer |  | No |
-| visibility | [v1.Visibility](#v1visibility) |  | No |
+| Name           | Type                                                             | Description            | Required |
+| -------------- | ---------------------------------------------------------------- | ---------------------- | -------- |
+| content        | string                                                           | Domain specific fields | No       |
+| createdTs      | integer                                                          | Standard fields        | No       |
+| relationList   | [ [v1.UpsertMemoRelationRequest](#v1upsertmemorelationrequest) ] |                        | No       |
+| resourceIdList | [ integer ]                                                      | Related fields         | No       |
+| rowStatus      | [v1.RowStatus](#v1rowstatus)                                     |                        | No       |
+| updatedTs      | integer                                                          |                        | No       |
+| visibility     | [v1.Visibility](#v1visibility)                                   |                        | No       |
 
 #### v1.Role
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| v1.Role | string |  |  |
+| Name    | Type   | Description | Required |
+| ------- | ------ | ----------- | -------- |
+| v1.Role | string |             |          |
 
 #### v1.RowStatus
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| v1.RowStatus | string |  |  |
+| Name         | Type   | Description | Required |
+| ------------ | ------ | ----------- | -------- |
+| v1.RowStatus | string |             |          |
 
 #### v1.SSOSignIn
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| code | string |  | No |
-| identityProviderId | integer |  | No |
-| redirectUri | string |  | No |
+| Name               | Type    | Description | Required |
+| ------------------ | ------- | ----------- | -------- |
+| code               | string  |             | No       |
+| identityProviderId | integer |             | No       |
+| redirectUri        | string  |             | No       |
 
 #### v1.SignIn
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| password | string |  | No |
-| username | string |  | No |
+| Name     | Type   | Description | Required |
+| -------- | ------ | ----------- | -------- |
+| password | string |             | No       |
+| username | string |             | No       |
 
 #### v1.SignUp
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| password | string |  | No |
-| username | string |  | No |
+| Name     | Type   | Description | Required |
+| -------- | ------ | ----------- | -------- |
+| password | string |             | No       |
+| username | string |             | No       |
 
 #### v1.StorageConfig
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| s3Config | [v1.StorageS3Config](#v1storages3config) |  | No |
+| Name     | Type                                     | Description | Required |
+| -------- | ---------------------------------------- | ----------- | -------- |
+| s3Config | [v1.StorageS3Config](#v1storages3config) |             | No       |
 
 #### v1.StorageS3Config
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| accessKey | string |  | No |
-| bucket | string |  | No |
-| endPoint | string |  | No |
-| path | string |  | No |
-| region | string |  | No |
-| secretKey | string |  | No |
-| urlPrefix | string |  | No |
-| urlSuffix | string |  | No |
+| Name      | Type   | Description | Required |
+| --------- | ------ | ----------- | -------- |
+| accessKey | string |             | No       |
+| bucket    | string |             | No       |
+| endPoint  | string |             | No       |
+| path      | string |             | No       |
+| region    | string |             | No       |
+| secretKey | string |             | No       |
+| urlPrefix | string |             | No       |
+| urlSuffix | string |             | No       |
 
 #### v1.StorageType
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| v1.StorageType | string |  |  |
+| Name           | Type   | Description | Required |
+| -------------- | ------ | ----------- | -------- |
+| v1.StorageType | string |             |          |
 
 #### v1.SystemSetting
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| description | string |  | No |
-| name | [v1.SystemSettingName](#v1systemsettingname) |  | No |
-| value | string | Value is a JSON string with basic value. | No |
+| Name        | Type                                         | Description                              | Required |
+| ----------- | -------------------------------------------- | ---------------------------------------- | -------- |
+| description | string                                       |                                          | No       |
+| name        | [v1.SystemSettingName](#v1systemsettingname) |                                          | No       |
+| value       | string                                       | Value is a JSON string with basic value. | No       |
 
 #### v1.SystemSettingName
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| v1.SystemSettingName | string |  |  |
+| Name                 | Type   | Description | Required |
+| -------------------- | ------ | ----------- | -------- |
+| v1.SystemSettingName | string |             |          |
 
 #### v1.SystemStatus
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| additionalScript | string | Additional script. | No |
-| additionalStyle | string | Additional style. | No |
-| allowSignUp | boolean | System settings Allow sign up. | No |
-| autoBackupInterval | integer | Auto Backup Interval. | No |
-| customizedProfile | [v1.CustomizedProfile](#v1customizedprofile) | Customized server profile, including server name and external url. | No |
-| dbSize | integer |  | No |
-| disablePasswordLogin | boolean | Disable password login. | No |
-| disablePublicMemos | boolean | Disable public memos. | No |
-| host | [v1.User](#v1user) |  | No |
-| localStoragePath | string | Local storage path. | No |
-| maxUploadSizeMiB | integer | Max upload size. | No |
-| memoDisplayWithUpdatedTs | boolean | Memo display with updated timestamp. | No |
-| profile | [profile.Profile](#profileprofile) |  | No |
-| storageServiceId | integer | Storage service ID. | No |
+| Name                     | Type                                         | Description                                                        | Required |
+| ------------------------ | -------------------------------------------- | ------------------------------------------------------------------ | -------- |
+| additionalScript         | string                                       | Additional script.                                                 | No       |
+| additionalStyle          | string                                       | Additional style.                                                  | No       |
+| allowSignUp              | boolean                                      | System settings Allow sign up.                                     | No       |
+| autoBackupInterval       | integer                                      | Auto Backup Interval.                                              | No       |
+| customizedProfile        | [v1.CustomizedProfile](#v1customizedprofile) | Customized server profile, including server name and external url. | No       |
+| dbSize                   | integer                                      |                                                                    | No       |
+| disablePasswordLogin     | boolean                                      | Disable password login.                                            | No       |
+| disablePublicMemos       | boolean                                      | Disable public memos.                                              | No       |
+| host                     | [v1.User](#v1user)                           |                                                                    | No       |
+| localStoragePath         | string                                       | Local storage path.                                                | No       |
+| maxUploadSizeMiB         | integer                                      | Max upload size.                                                   | No       |
+| memoDisplayWithUpdatedTs | boolean                                      | Memo display with updated timestamp.                               | No       |
+| profile                  | [profile.Profile](#profileprofile)           |                                                                    | No       |
+| storageServiceId         | integer                                      | Storage service ID.                                                | No       |
 
 #### v1.UpdateIdentityProviderRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| config | [v1.IdentityProviderConfig](#v1identityproviderconfig) |  | No |
-| identifierFilter | string |  | No |
-| name | string |  | No |
-| type | [v1.IdentityProviderType](#v1identityprovidertype) |  | No |
+| Name             | Type                                                   | Description | Required |
+| ---------------- | ------------------------------------------------------ | ----------- | -------- |
+| config           | [v1.IdentityProviderConfig](#v1identityproviderconfig) |             | No       |
+| identifierFilter | string                                                 |             | No       |
+| name             | string                                                 |             | No       |
+| type             | [v1.IdentityProviderType](#v1identityprovidertype)     |             | No       |
 
 #### v1.UpdateResourceRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| filename | string |  | No |
+| Name     | Type   | Description | Required |
+| -------- | ------ | ----------- | -------- |
+| filename | string |             | No       |
 
 #### v1.UpdateStorageRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| config | [v1.StorageConfig](#v1storageconfig) |  | No |
-| name | string |  | No |
-| type | [v1.StorageType](#v1storagetype) |  | No |
+| Name   | Type                                 | Description | Required |
+| ------ | ------------------------------------ | ----------- | -------- |
+| config | [v1.StorageConfig](#v1storageconfig) |             | No       |
+| name   | string                               |             | No       |
+| type   | [v1.StorageType](#v1storagetype)     |             | No       |
 
 #### v1.UpdateUserRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| avatarUrl | string |  | No |
-| email | string |  | No |
-| nickname | string |  | No |
-| password | string |  | No |
-| rowStatus | [v1.RowStatus](#v1rowstatus) |  | No |
-| username | string |  | No |
+| Name      | Type                         | Description | Required |
+| --------- | ---------------------------- | ----------- | -------- |
+| avatarUrl | string                       |             | No       |
+| email     | string                       |             | No       |
+| nickname  | string                       |             | No       |
+| password  | string                       |             | No       |
+| rowStatus | [v1.RowStatus](#v1rowstatus) |             | No       |
+| username  | string                       |             | No       |
 
 #### v1.UpsertMemoOrganizerRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| pinned | boolean |  | No |
+| Name   | Type    | Description | Required |
+| ------ | ------- | ----------- | -------- |
+| pinned | boolean |             | No       |
 
 #### v1.UpsertMemoRelationRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| relatedMemoId | integer |  | No |
-| type | [v1.MemoRelationType](#v1memorelationtype) |  | No |
+| Name          | Type                                       | Description | Required |
+| ------------- | ------------------------------------------ | ----------- | -------- |
+| relatedMemoId | integer                                    |             | No       |
+| type          | [v1.MemoRelationType](#v1memorelationtype) |             | No       |
 
 #### v1.UpsertSystemSettingRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| description | string |  | No |
-| name | [v1.SystemSettingName](#v1systemsettingname) |  | No |
-| value | string |  | No |
+| Name        | Type                                         | Description | Required |
+| ----------- | -------------------------------------------- | ----------- | -------- |
+| description | string                                       |             | No       |
+| name        | [v1.SystemSettingName](#v1systemsettingname) |             | No       |
+| value       | string                                       |             | No       |
 
 #### v1.UpsertTagRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| name | string |  | No |
+| Name | Type   | Description | Required |
+| ---- | ------ | ----------- | -------- |
+| name | string |             | No       |
 
 #### v1.UpsertUserSettingRequest
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| key | [v1.UserSettingKey](#v1usersettingkey) |  | No |
-| value | string |  | No |
+| Name  | Type                                   | Description | Required |
+| ----- | -------------------------------------- | ----------- | -------- |
+| key   | [v1.UserSettingKey](#v1usersettingkey) |             | No       |
+| value | string                                 |             | No       |
 
 #### v1.User
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| avatarUrl | string |  | No |
-| createdTs | integer |  | No |
-| email | string |  | No |
-| id | integer |  | No |
-| nickname | string |  | No |
-| role | [v1.Role](#v1role) |  | No |
-| rowStatus | [v1.RowStatus](#v1rowstatus) | Standard fields | No |
-| updatedTs | integer |  | No |
-| userSettingList | [ [v1.UserSetting](#v1usersetting) ] |  | No |
-| username | string | Domain specific fields | No |
+| Name            | Type                                 | Description            | Required |
+| --------------- | ------------------------------------ | ---------------------- | -------- |
+| avatarUrl       | string                               |                        | No       |
+| createdTs       | integer                              |                        | No       |
+| email           | string                               |                        | No       |
+| id              | integer                              |                        | No       |
+| nickname        | string                               |                        | No       |
+| role            | [v1.Role](#v1role)                   |                        | No       |
+| rowStatus       | [v1.RowStatus](#v1rowstatus)         | Standard fields        | No       |
+| updatedTs       | integer                              |                        | No       |
+| userSettingList | [ [v1.UserSetting](#v1usersetting) ] |                        | No       |
+| username        | string                               | Domain specific fields | No       |
 
 #### v1.UserSetting
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| key | [v1.UserSettingKey](#v1usersettingkey) |  | No |
-| userId | integer |  | No |
-| value | string |  | No |
+| Name   | Type                                   | Description | Required |
+| ------ | -------------------------------------- | ----------- | -------- |
+| key    | [v1.UserSettingKey](#v1usersettingkey) |             | No       |
+| userId | integer                                |             | No       |
+| value  | string                                 |             | No       |
 
 #### v1.UserSettingKey
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| v1.UserSettingKey | string |  |  |
+| Name              | Type   | Description | Required |
+| ----------------- | ------ | ----------- | -------- |
+| v1.UserSettingKey | string |             |          |
 
 #### v1.Visibility
 
-| Name | Type | Description | Required |
-| ---- | ---- | ----------- | -------- |
-| v1.Visibility | string |  |  |
+| Name          | Type   | Description | Required |
+| ------------- | ------ | ----------- | -------- |
+| v1.Visibility | string |             |          |

programming_language: Markdown