Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions docs/notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"
```
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
13 changes: 10 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions src/components/settings_view.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,18 @@
error={true}
/>
{/if}
<ObsidianSettingsItem
name="Testing HTTPS request on mobile"
description="The following settings is a test for HTTPS request on mobile."
>
<svelte:fragment slot="control">
<button
on:click={() => parent.plugin.syncthingFromREST.getMobileStatus()}
>
Get status
</button>
</svelte:fragment>
</ObsidianSettingsItem>

<!-- GUI Setting -->
<ObsidianSettingsItem name="Syncthing base URL" heading={true} />
Expand Down
76 changes: 74 additions & 2 deletions src/data/syncthing_remote_datasource.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -83,14 +84,24 @@ export class SyncthingFromREST {
return SyncthingConfigurationModel.fromJSON(response.json);
}

/**
* 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 `/`.
*
* @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<RequestUrlResponse> {
// 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;
Expand All @@ -106,6 +117,7 @@ export class SyncthingFromREST {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
redirect: "follow",
// ca: [fs.readFileSync("CA_cert.pem")],
},
});
console.log(
Expand All @@ -126,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.

Check failure

Code scanning / CodeQL

Disabling certificate validation

Disabling certificate validation is strongly discouraged.
}),
};
// 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;
}
}
}