From 009d4cf63db89ffbd933962a6da8445424dd178e Mon Sep 17 00:00:00 2001 From: LBF38 Date: Sun, 27 Aug 2023 20:16:20 +0200 Subject: [PATCH 1/3] chore(dev): :twisted_rightwards_arrows: rebase branch on master --- src/data/syncthing_remote_datasource.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/data/syncthing_remote_datasource.ts b/src/data/syncthing_remote_datasource.ts index a1ab75e..fc492a3 100644 --- a/src/data/syncthing_remote_datasource.ts +++ b/src/data/syncthing_remote_datasource.ts @@ -83,6 +83,13 @@ export class SyncthingFromREST { return SyncthingConfigurationModel.fromJSON(response.json); } + /** + * Private method to request an endpoint of the REST API. + * The endpoint should start with a `/`. + * + * @param endpoint - The REST endpoint to call. @see https://docs.syncthing.net/dev/rest.html + * @returns The response of the REST API. + */ /** * Private method to request an endpoint of the REST API. * The endpoint should start with a `/`. From 0279a9646383ceb2a823a8cf422efb2f68893b23 Mon Sep 17 00:00:00 2001 From: LBF38 Date: Tue, 19 Sep 2023 11:40:35 +0200 Subject: [PATCH 2/3] docs(syncthing): :memo: add notes on the HTTPS certificates and self-signed certs --- docs/notes.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/docs/notes.md b/docs/notes.md index 7b5969c..c5ca900 100644 --- a/docs/notes.md +++ b/docs/notes.md @@ -102,3 +102,66 @@ Here are the main features that the mobile UI should have : - [ ] Through opening the Play Store app page. - [ ] Through opening the Syncthing app if installed. - [ ] Add/remove folders and/or files to the Syncthing configuration through commands/settings tab. => can choose which files are synchronized with other devices. (usage of the `.stignore` file) + +## Steps to follow to change the HTTPS certificate for the Syncthing GUI/API + +From the `openssl` cli, run the following command to generate a new certificate: + +- Generate a private key: + +```bash +openssl genrsa -out https-key.pem 2048 +``` + +- Generate a certificate signing request (CSR): + +```bash +openssl req -new -key https-key.pem -out https-csr.pem +``` + +- Generate a self-signed certificate: + +```bash +openssl x509 -req -in https-csr.pem -signkey https-key.pem -out https-cert.pem +``` + +- To create a `.cer` file from a `.pem` file, run the following command: + +```bash +openssl x509 -in https-cert.pem -outform der -out https-cert.cer +``` + +An example of a SAN configuration for adding a Subject Alternative Name (SAN) to the certificate: + +```toml +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] + +[v3_req] +subjectAltName = @alt_names + +[alt_names] +DNS.1 = localhost +# Add more DNS entries if needed +``` + +To generate a certificate signing request (CSR) with the SAN extension, you can use the following command: + +```bash +openssl req -new -key https-key.pem -out https-csr.pem -config san.cnf +``` + +We can also directly use the `openssl` cli to add SAN to the certificate: + +```bash +openssl req -new -x509 -key https-key.pem -out https-cert.pem -subj "/CN=localhost" -addext "subjectAltName = DNS:localhost" +``` + +For generating the certificate with the SAN extension, we can use the following command: + +```bash +openssl req -new -x509 -key https-key.pem -out https-cert.pem -subj "/CN=mathismsi/O=Syncthing/OU=Automatically Generated" -addext "subjectAltName = DNS:localhost" +``` From be2ce0da5f717637f8166d23dfb7e2fc22395dec Mon Sep 17 00:00:00 2001 From: LBF38 Date: Tue, 19 Sep 2023 11:43:55 +0200 Subject: [PATCH 3/3] feat(mobile): :construction: TO REVERT: test on HTTPS request on mobile --- package.json | 1 + pnpm-lock.yaml | 13 +++- src/components/settings_view.svelte | 12 ++++ src/data/syncthing_remote_datasource.ts | 79 ++++++++++++++++++++++--- 4 files changed, 95 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 67e3a52..2cced68 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "eslint-plugin-svelte": "^2.32.4", "fs": "0.0.1-security", "highlight.js": "^11.8.0", + "https": "^1.0.0", "husky": "^8.0.0", "lorem-ipsum": "^2.0.8", "marked": "^5.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 170ecf2..06e02e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -86,6 +86,9 @@ devDependencies: highlight.js: specifier: ^11.8.0 version: 11.8.0 + https: + specifier: ^1.0.0 + version: 1.0.0 husky: specifier: ^8.0.0 version: 8.0.0 @@ -100,7 +103,7 @@ devDependencies: version: 0.40.0 obsidian: specifier: latest - version: 1.4.0(@codemirror/state@6.2.1)(@codemirror/view@6.13.0) + version: 1.4.4(@codemirror/state@6.2.1)(@codemirror/view@6.13.0) sass: specifier: ^1.62.1 version: 1.62.1 @@ -2409,6 +2412,10 @@ packages: - supports-color dev: true + /https@1.0.0: + resolution: {integrity: sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==} + dev: true + /human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -3127,8 +3134,8 @@ packages: boolbase: 1.0.0 dev: true - /obsidian@1.4.0(@codemirror/state@6.2.1)(@codemirror/view@6.13.0): - resolution: {integrity: sha512-fsZMPlxgflGSBSP6P4BjQi5+0MqZl3h6FEDEZ3CNnweNdDw0doyqN3FMO/PGWfuxPT77WicVwUxekuI3e6eCGg==} + /obsidian@1.4.4(@codemirror/state@6.2.1)(@codemirror/view@6.13.0): + resolution: {integrity: sha512-q2V5GNT/M40uYOENdVw5kovPSoaO6vppiiyBCkIqWgKp4oN654jA/GQ0OaNBA7p5NdfS245QCeRgCFQ42wOZiw==} peerDependencies: '@codemirror/state': ^6.0.0 '@codemirror/view': ^6.0.0 diff --git a/src/components/settings_view.svelte b/src/components/settings_view.svelte index e20e9fb..ec2a00b 100644 --- a/src/components/settings_view.svelte +++ b/src/components/settings_view.svelte @@ -170,6 +170,18 @@ error={true} /> {/if} + + + + + diff --git a/src/data/syncthing_remote_datasource.ts b/src/data/syncthing_remote_datasource.ts index fc492a3..f1c0c16 100644 --- a/src/data/syncthing_remote_datasource.ts +++ b/src/data/syncthing_remote_datasource.ts @@ -1,4 +1,5 @@ -import { Platform, requestUrl } from "obsidian"; +import https from "https"; +import { Platform, RequestUrlResponse, requestUrl } from "obsidian"; import SyncthingPlugin from "src/main"; import { SyncthingDevice } from "src/models/entities"; import { RestFailure } from "src/models/failures"; @@ -84,12 +85,13 @@ export class SyncthingFromREST { } /** - * Private method to request an endpoint of the REST API. - * The endpoint should start with a `/`. - * - * @param endpoint - The REST endpoint to call. @see https://docs.syncthing.net/dev/rest.html - * @returns The response of the REST API. + * Test API for HTTPS request on mobile */ + async getMobileStatus() { + await this.requestEndpointMobile("/rest/system/ping"); + // console.log(response); + } + /** * Private method to request an endpoint of the REST API. * The endpoint should start with a `/`. @@ -97,7 +99,9 @@ export class SyncthingFromREST { * @param endpoint - The REST endpoint to call. @see https://docs.syncthing.net/dev/rest.html * @returns The response of the REST API. */ - private async requestEndpoint(endpoint: string) { + private async requestEndpoint( + endpoint: string + ): Promise { // FIXME: Fix the issue when connecting to the REST API. (error 403) console.log("requestEndpoint: Endpoint", endpoint); let ip_address = this.plugin.settings.configuration.url?.ip_address; @@ -113,6 +117,7 @@ export class SyncthingFromREST { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*", redirect: "follow", + // ca: [fs.readFileSync("CA_cert.pem")], }, }); console.log( @@ -133,4 +138,64 @@ export class SyncthingFromREST { throw new RestFailure(error); }); } + + /** + * Private method to request an endpoint on mobile. + * Test for making HTTPS requests on mobile. + */ + private async requestEndpointMobile(endpoint: string) { + console.log("requestEndpointMobile: Endpoint", endpoint); + let ip_address = this.plugin.settings.configuration.url?.ip_address; + if (ip_address === "localhost") { + ip_address = "127.0.0.1"; + } + if ( + // Platform.isMobileApp && + this.plugin.settings.configuration.url?.protocol === "https" + ) { + console.log("requestEndpoint: Mobile App"); + const options = { + hostname: ip_address, + port: this.plugin.settings.configuration.url?.port, + path: endpoint, + method: "GET", + headers: { + "X-API-Key": this.plugin.settings.api_key, + Accept: "*/*", + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + redirect: "follow", + }, + agent: new https.Agent({ + rejectUnauthorized: false, // works on desktop but not on mobile. + }), + }; + // let response: RequestUrlResponse; + console.log("requestEndpointMobile: ", options); + + const req = https.request(options, (res) => { + console.log("statusCode:", res.statusCode); + console.log("headers:", res.headers); + if (!res.statusCode) throw new RestFailure("No status code"); + // response.status = res.statusCode; + const chunck: Uint8Array[] = []; + res.on("data", (d) => { + console.log("data stream: ", d, d.buffer); + chunck.push(d); + }); + res.on("end", () => { + const data = Buffer.concat(chunck); + console.log("data: ", data, data.toString()); + }); + }); + req.on("connection", (e) => { + console.log("connection: ", e); + }); + req.on("error", (e) => { + console.error(e); + }); + req.end(); + // return response; + } + } }