diff --git a/docs/Release Notes/!!!meta.json b/docs/Release Notes/!!!meta.json index c9e9b98a2..9a5c041f1 100644 --- a/docs/Release Notes/!!!meta.json +++ b/docs/Release Notes/!!!meta.json @@ -61,7 +61,7 @@ "hD3V4hiu2VW4", "VN3xnce1vLkX" ], - "title": "v0.92.8-beta", + "title": "v0.93.0", "notePosition": 10, "prefix": null, "isExpanded": false, @@ -69,7 +69,7 @@ "mime": "text/html", "attributes": [], "format": "markdown", - "dataFileName": "v0.92.8-beta.md", + "dataFileName": "v0.93.0.md", "attachments": [] }, { diff --git a/docs/Release Notes/Release Notes/v0.92.8-beta.md b/docs/Release Notes/Release Notes/v0.93.0.md similarity index 91% rename from docs/Release Notes/Release Notes/v0.92.8-beta.md rename to docs/Release Notes/Release Notes/v0.93.0.md index 3b99b9519..56726e070 100644 --- a/docs/Release Notes/Release Notes/v0.92.8-beta.md +++ b/docs/Release Notes/Release Notes/v0.93.0.md @@ -1,4 +1,4 @@ -# v0.92.8-beta +# v0.93.0 ## 💡 Key highlights * … @@ -14,6 +14,7 @@ * [Note background is gray in 0.92.7 (light theme)](https://github.com/TriliumNext/Notes/issues/1689) * [config.Session.cookieMaxAge is ignored](https://github.com/TriliumNext/Notes/issues/1709) by @pano9000 * [Return correct HTTP status code on failed login attempts instead of 200](https://github.com/TriliumNext/Notes/issues/1707) by @pano9000 +* [Calendar stops displaying notes after adding a Day Note](https://github.com/TriliumNext/Notes/issues/1705) ## ✨ Improvements @@ -32,6 +33,7 @@ * [Center Search results under quick search bar](https://github.com/TriliumNext/Notes/issues/1679) * Native ARM builds for Windows are now back. * Basic Touch Bar support for macOS. +* [Support Bearer Token](https://github.com/TriliumNext/Notes/issues/1701) ## 🌍 Internationalization diff --git a/docs/User Guide/!!!meta.json b/docs/User Guide/!!!meta.json index b548e1846..cd9f21f61 100644 --- a/docs/User Guide/!!!meta.json +++ b/docs/User Guide/!!!meta.json @@ -9636,6 +9636,13 @@ "isInheritable": false, "position": 10 }, + { + "type": "relation", + "name": "internalLink", + "value": "habiZ3HU8Kw8", + "isInheritable": false, + "position": 20 + }, { "type": "relation", "name": "internalLink", @@ -9649,13 +9656,6 @@ "value": "default-note-title", "isInheritable": false, "position": 30 - }, - { - "type": "relation", - "name": "internalLink", - "value": "habiZ3HU8Kw8", - "isInheritable": false, - "position": 20 } ], "format": "markdown", @@ -10014,6 +10014,13 @@ "isInheritable": false, "position": 40 }, + { + "type": "relation", + "name": "internalLink", + "value": "habiZ3HU8Kw8", + "isInheritable": false, + "position": 50 + }, { "type": "relation", "name": "internalLink", @@ -10027,13 +10034,6 @@ "value": "bx bx-list-plus", "isInheritable": false, "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "habiZ3HU8Kw8", - "isInheritable": false, - "position": 50 } ], "format": "markdown", @@ -11066,32 +11066,32 @@ "mime": "text/markdown", "attributes": [ { - "type": "label", - "name": "shareAlias", - "value": "script-api", + "type": "relation", + "name": "internalLink", + "value": "CdNpE2pqjmI6", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "CdNpE2pqjmI6", + "value": "Q2z6av6JZVWm", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "Q2z6av6JZVWm", + "value": "MEtfsqa5VwNi", "isInheritable": false, "position": 30 }, { - "type": "relation", - "name": "internalLink", - "value": "MEtfsqa5VwNi", + "type": "label", + "name": "shareAlias", + "value": "script-api", "isInheritable": false, - "position": 40 + "position": 10 } ], "format": "markdown", diff --git a/docs/User Guide/User Guide/Advanced Usage/ETAPI (REST API).md b/docs/User Guide/User Guide/Advanced Usage/ETAPI (REST API).md index b9c4db4f3..c24200049 100644 --- a/docs/User Guide/User Guide/Advanced Usage/ETAPI (REST API).md +++ b/docs/User Guide/User Guide/Advanced Usage/ETAPI (REST API).md @@ -9,16 +9,26 @@ As an alternative to calling the API directly, there are client libraries to sim * [trilium-py](https://github.com/Nriver/trilium-py), you can use Python to communicate with Trilium. +## Obtaining a token + +All operations with the REST API have to be authenticated using a token. You can get this token either from Options -> ETAPI or programmatically using the `/auth/login` REST call (see the [spec](https://github.com/TriliumNext/Notes/blob/master/src/etapi/etapi.openapi.yaml)). + ## Authentication -All operations have to be authenticated using a token. You can get this token either from Options -> ETAPI or programmatically using the `/auth/login` REST call (see the [spec](https://github.com/TriliumNext/Notes/blob/master/src/etapi/etapi.openapi.yaml)): +### Via the `Authorization` header ``` GET https://myserver.com/etapi/app-info Authorization: ETAPITOKEN ``` -Alternatively, since 0.56 you can also use basic auth format: +where `ETAPITOKEN` is the token obtained in the previous step. + +For compatibility with various tools, it's also possible to specify the value of the `Authorization` header in the format `Bearer ETAPITOKEN` (since 0.93.0). + +### Basic authentication + +Since v0.56 you can also use basic auth format: ``` GET https://myserver.com/etapi/app-info diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Advanced Usage/ETAPI (REST API).html b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced Usage/ETAPI (REST API).html index 0aa779d60..a7ea78e55 100644 --- a/src/public/app/doc_notes/en/User Guide/User Guide/Advanced Usage/ETAPI (REST API).html +++ b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced Usage/ETAPI (REST API).html @@ -8,12 +8,19 @@
  • trilium-py, you can use Python to communicate with Trilium.
  • +

    Obtaining a token

    +

    All operations with the REST API have to be authenticated using a token. + You can get this token either from Options -> ETAPI or programmatically + using the /auth/login REST call (see the spec).

    Authentication

    -

    All operations have to be authenticated using a token. You can get this - token either from Options -> ETAPI or programmatically using the /auth/login REST - call (see the spec):

    GET https://myserver.com/etapi/app-info
    +

    Via the Authorization header

    GET https://myserver.com/etapi/app-info
     Authorization: ETAPITOKEN
    -

    Alternatively, since 0.56 you can also use basic auth format:

    GET https://myserver.com/etapi/app-info
    +

    where ETAPITOKEN is the token obtained in the previous step.

    +

    For compatibility with various tools, it's also possible to specify the + value of the Authorization header in the format Bearer ETAPITOKEN (since + 0.93.0).

    +

    Basic authentication

    +

    Since v0.56 you can also use basic auth format:

    GET https://myserver.com/etapi/app-info
     Authorization: Basic BATOKEN
    • Where BATOKEN = BASE64(username + ':' + password) - this is diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker.html b/src/public/app/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker.html index 72b77aef3..26e837d8b 100644 --- a/src/public/app/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker.html +++ b/src/public/app/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker.html @@ -36,8 +36,8 @@

      Running the Docker Container

      Local Access Only

      Run the container to make it accessible only from the localhost. This - setup is suitable for testing or when using a prox ay server like Nginx - or Apache.

      sudo docker run -t -i -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/notes:[VERSION]
      + setup is suitable for testing or when using a proxy server like Nginx or + Apache.

      sudo docker run -t -i -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/notes:[VERSION]
      1. Verify the container is running using docker ps.
      2. Access Trilium via a web browser at 127.0.0.1:8080.
      3. diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Scripting/Script API.html b/src/public/app/doc_notes/en/User Guide/User Guide/Scripting/Script API.html index a2ea49ead..25b181b48 100644 --- a/src/public/app/doc_notes/en/User Guide/User Guide/Scripting/Script API.html +++ b/src/public/app/doc_notes/en/User Guide/User Guide/Scripting/Script API.html @@ -1,11 +1,10 @@ -

        For script code notes, - Trilium offers an API that gives them access to various features of the - application.

        +

        For script code notes, Trilium offers + an API that gives them access to various features of the application.

        There are two APIs:

        In both cases, the API resides in a global variable, api, diff --git a/src/services/etapi_tokens.ts b/src/services/etapi_tokens.ts index 93d916a60..031856f2a 100644 --- a/src/services/etapi_tokens.ts +++ b/src/services/etapi_tokens.ts @@ -48,6 +48,11 @@ function parseAuthToken(auth: string | undefined) { auth = basicAuthChunks[1]; } + if (auth.startsWith("Bearer ")) { + // allow also bearer auth format + auth = auth.substring(7); + } + const chunks = auth.split("_"); if (chunks.length === 1) { diff --git a/src/services/sql.ts b/src/services/sql.ts index d135b54da..f686b0876 100644 --- a/src/services/sql.ts +++ b/src/services/sql.ts @@ -112,12 +112,21 @@ function upsert(tableName: string, primaryKey: string, rec: T) { execute(query, rec); } -function stmt(sql: string) { - if (!(sql in statementCache)) { - statementCache[sql] = dbConnection.prepare(sql); +/** + * For the given SQL query, returns a prepared statement. For the same query (string comparison), the same statement is returned. + * + * @param sql the SQL query for which to return a prepared statement. + * @param isRaw indicates whether `.raw()` is going to be called on the prepared statement in order to return the raw rows (e.g. via {@link getRawRows()}). The reason is that the raw state is preserved in the saved statement and would break non-raw calls for the same query. + * @returns the corresponding {@link Statement}. + */ +function stmt(sql: string, isRaw?: boolean) { + const key = (isRaw ? "raw/" + sql : sql); + + if (!(key in statementCache)) { + statementCache[key] = dbConnection.prepare(sql); } - return statementCache[sql]; + return statementCache[key]; } function getRow(query: string, params: Params = []): T { @@ -172,7 +181,7 @@ function getRows(query: string, params: Params = []): T[] { } function getRawRows(query: string, params: Params = []): T[] { - return (wrap(query, (s) => s.raw().all(params)) as T[]) || []; + return (wrap(query, (s) => s.raw().all(params), true) as T[]) || []; } function iterateRows(query: string, params: Params = []): IterableIterator { @@ -234,7 +243,10 @@ function executeScript(query: string): DatabaseType { return dbConnection.exec(query); } -function wrap(query: string, func: (statement: Statement) => unknown): unknown { +/** + * @param isRaw indicates whether `.raw()` is going to be called on the prepared statement in order to return the raw rows (e.g. via {@link getRawRows()}). The reason is that the raw state is preserved in the saved statement and would break non-raw calls for the same query. + */ +function wrap(query: string, func: (statement: Statement) => unknown, isRaw?: boolean): unknown { const startTimestamp = Date.now(); let result; @@ -243,7 +255,7 @@ function wrap(query: string, func: (statement: Statement) => unknown): unknown { } try { - result = func(stmt(query)); + result = func(stmt(query, isRaw)); } catch (e: any) { if (e.message.includes("The database connection is not open")) { // this often happens on killing the app which puts these alerts in front of user