diff --git a/src/content/guides/pawnote/en/authentication.md b/src/content/guides/pawnote/en/authentication.md new file mode 100644 index 0000000..480f912 --- /dev/null +++ b/src/content/guides/pawnote/en/authentication.md @@ -0,0 +1,98 @@ +--- +title: Authentication +description: Probably the first thing you want to do when using Pawnote is authenticating to your account, otherwise you won't be able to do much. +--- + +import { Tabs, TabItem, Code } from '@astrojs/starlight/components'; + +You can authenticate to PRONOTE using three different methods : + +- [Credentials](#credentials) +- [QR Code](#qr-code) +- [Token](#token) : usually called the "next time token" + +## Credentials + +You can use your credentials from PRONOTE to directly authenticate. + +```typescript +import { authenticatePronoteCredentials, PronoteApiAccountId } from "pawnote"; + +const client = await authenticatePronoteCredentials("https://demo.index-education.net/pronote", { + accountTypeID: PronoteApiAccountId.Student, + username: "demonstration", + password: "pronotevs", + + // An unique identifier that will be used to identify the device. + deviceUUID: "my-device-uuid" +}); +``` + +## QR Code + +You can generate a QR Code from the desktop PRONOTE client by doing the following : + +![Create a QR Code](../../../../assets/screenshots/pronote-qr-code-setup.png) + +You must enter a PIN code, here I typed `1234`, don't forget it we'll use it later. +By clicking "Générer le QR Code", you'll see a window giving you a QR Code that looks like this : + +![QR Code](../../../../assets/screenshots/pronote-qr-code.png) + +You should decode it manually. You can use online services like [zxing.org](https://zxing.org/w/decode.jspx) to decode it. + +For the previous QR Code, you should get the following data : + +```jsonc +{ + "jeton": "B88BE6BEEFE21F3AFF13457CD74B28728A61D2CE4DBB0E92E6BBAD26D110B99E50EF6A0529F7B5FFFCEFA7739452F22462642A3AD77B3BF2AAD34EBC9385A406C50BF6934F77B5082FF89D080253307DF8F48C7EF44EE2197879ECBD4BFD10F132659269B115F57AD495B0E01AB9F5F0", + "login": "E641C7BAD9A59DC9D57C63F1D682895C", + // This is the URL of my private VM instance. + "url": "https://pronote-vm.dev/pronote/mobile.eleve.html" +} +``` + +Now you can simply authenticate with Pawnote using the following code : + +```typescript +import { authenticatePronoteQRCode } from "pawnote"; + +const client = await authenticatePronoteQRCode({ + // The 4 numbers you typed earlier. + pinCode: "1234", + + // This is the data from the QR Code. + dataFromQRCode: { + jeton: "B88BE6BEEFE21F3AFF13457CD74B28728A61D2CE4DBB0E92E6BBAD26D110B99E50EF6A0529F7B5FFFCEFA7739452F22462642A3AD77B3BF2AAD34EBC9385A406C50BF6934F77B5082FF89D080253307DF8F48C7EF44EE2197879ECBD4BFD10F132659269B115F57AD495B0E01AB9F5F0", + login: "E641C7BAD9A59DC9D57C63F1D682895C", + url: "https://pronote-vm.dev/pronote/mobile.eleve.html" + }, + + // An unique identifier that will be used to identify the device. + deviceUUID: "my-device-uuid" +}); +``` + +## Token + +You can use the "next time token" to authenticate to PRONOTE. +This token is given whenever you authenticate (using whatever method) to PRONOTE and is availablle only one time. + +As its name suggests, it's used to authenticate the next time you want to authenticate. + +**You should use the same device UUID as you used to generate the token.** + +Also note that this method doesn't work on demo instances (like `https://demo.index-education.net/pronote`), you must use a real instance. + +```typescript +import { authenticateToken, PronoteApiAccountId } from "pawnote"; + +const client = await authenticateToken("https://pronote-vm.dev/pronote", { + accountTypeID: PronoteApiAccountId.Student, + username: "lisa.boulanger", + token: "...", + + // You must keep the SAME device UUID as the one you used to generate the token. + deviceUUID: "my-device-uuid" +}); +``` diff --git a/src/content/guides/pawnote/en/hello.md b/src/content/guides/pawnote/en/hello.md deleted file mode 100644 index c522f7f..0000000 --- a/src/content/guides/pawnote/en/hello.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Hello ! ---- - -Welcome to Pawnote, the note-taking app that helps you to organize your thoughts and ideas. - -You might go back to [guide summary](./). diff --git a/src/content/guides/pawnote/en/installation.md b/src/content/guides/pawnote/en/installation.md new file mode 100644 index 0000000..8dd148b --- /dev/null +++ b/src/content/guides/pawnote/en/installation.md @@ -0,0 +1,30 @@ +--- +title: Installation +description: Want to integrate Pawnote in your project? Here's how to get started. +--- + +## JavaScript / TypeScript + +```bash +pnpm add pawnote +# or +yarn add pawnote +# or +npm install --save pawnote +``` + +## Dart / Flutter + +Pawnote is **currently not available** on `pub.dev` since it's still a work in progress, even though, in the future you might be able to install it using the following command. + +```bash +dart pub add pawnote +# or +flutter pub add pawnote +``` + +You'll be able to use Pawnote using the following import : + +```dart +import "package:pawnote/pawnote.dart"; +``` diff --git a/src/content/guides/pawnote/en/js/tauri.md b/src/content/guides/pawnote/en/js/tauri.md new file mode 100644 index 0000000..cafdf58 --- /dev/null +++ b/src/content/guides/pawnote/en/js/tauri.md @@ -0,0 +1,37 @@ +--- +title: Tauri +description: Want to make Pawnote run under Tauri ? Here's how to do it. +--- + +## Fetcher (for Tauri v1) + +Since Pawnote uses [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) as default fetcher, you need to create a custom fetcher to make it work with the [Tauri HTTP API](https://tauri.app/v1/api/js/http). + +Here's a simple one that should always work for Pawnote: + +```typescript +import { type PawnoteFetcher } from "pawnote"; +import { Body, ResponseType, getClient } from "@tauri-apps/api/http"; + +const tauriPawnoteFetcher: PawnoteFetcher = async (url, options) => { + const client = await getClient(options.redirect === "manual" ? { + maxRedirections: 0 + } : void 0); + + const response = await client.request({ + url, + method: options.method, + headers: options.headers, + body: options.method !== "GET" && options.body ? Body.text(options.body) : void 0, + responseType: ResponseType.Text + }); + + return { + headers: response.headers, + text: async () => response.data, + json: async () => JSON.parse(response.data) as T + } +}; + +export default tauriPawnoteFetcher; +``` diff --git a/src/content/guides/pawnote/en/pronote-internals/instance-url-parameters.md b/src/content/guides/pawnote/en/pronote-internals/instance-url-parameters.md new file mode 100644 index 0000000..c33f0dd --- /dev/null +++ b/src/content/guides/pawnote/en/pronote-internals/instance-url-parameters.md @@ -0,0 +1,21 @@ +--- +title: Instance URL parameters +description: Those parameters that some of y'all know about, but some of them are unknown to the public. +--- + +## Bypass the ENT using `login=1` + +Sometimes, you don't login using your credentials on Pronote, but with a web portal and this is called an ENT. +It's setup by your school, and it's a way to authenticate you without giving your credentials to Pronote. + +Even though, there's a way to bypass it and use your Pronote credentials to authenticate. + +Use the `login=1` parameter in the URL to bypass the ENT. + +Example: `https://example.com/?login=1` + +## Bypass potential incompatibility with browsers using `fd=1` + +On a browser such like this one : `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15`, you might encounter a warning when loading the website that says that your browser is not compatible. + +Anyway, you can bypass this warning by adding the `fd=1` parameter in the URL. diff --git a/src/content/guides/pawnote/en/pronote-internals/introduction.md b/src/content/guides/pawnote/en/pronote-internals/introduction.md new file mode 100644 index 0000000..102d8f0 --- /dev/null +++ b/src/content/guides/pawnote/en/pronote-internals/introduction.md @@ -0,0 +1,8 @@ +--- +title: Introduction +description: Why do I need to know those things when contributing ? +--- + +Pronote is a very large piece of software, and it's not always *easy* to understand how it works. + +This is why we maintain this documentation, to help you understand how it works and potentially contribute to Pawnote or write your own library. diff --git a/src/content/guides/pawnote/en/pronote-internals/toutatice-url.md b/src/content/guides/pawnote/en/pronote-internals/toutatice-url.md new file mode 100644 index 0000000..72d8f0d --- /dev/null +++ b/src/content/guides/pawnote/en/pronote-internals/toutatice-url.md @@ -0,0 +1,72 @@ +--- +title: Handling Toutatice URLs +description: Toutatice URLs system +--- + +In the development of applications that interact with the Pronote system, it is important to understand the peculiarities of URLs associated with the Toutatice domain. This note provides a comprehensive explanation of the specific characteristics of Toutatice URLs and offers practical guidance for handling them effectively in real-world applications. + +## Background + +Schools have unique URLs to access their Pronote instances, typically formatted as `https://[school-code].index-education.net/`. However, some institutions use an alternative domain, `https://[school-code].pronote.toutatice.fr/`, which can lead to confusion and connection issues if not handled correctly. + +## Identifying Toutatice URLs + +### Typical Pronote URL Structure + +A standard Pronote URL is structured as follows : +`https://[school-code].index-education.net/` + +### Toutatice URL Structure + +For schools that use the Toutatice domain, the URL structure is : +`https://[school-code].pronote.toutatice.fr/` + +### Handling URL Failures + +When interacting with Pronote instances, your application might initially attempt to connect using the `index-education.net` domain. If this connection fails, it is important to retry using the `pronote.toutatice.fr` domain. The following sections outline the steps and code required to handle such cases. + +### Implementation Example + +Below is an example implementation in JavaScript from [Papillon](https://github.com/PapillonApp/Papillon), how to handle the URL switch when a connection attempt fails: + +```javascript +try { + const information = await getPronoteInstanceInformation(defaultPawnoteFetcher, { + pronoteURL + }); + + return information; +} +catch { + try { + // Replace the domain in the URL + pronoteURL = pronoteURL.replace(".index-education.net", ".pronote.toutatice.fr"); + console.log("Trying with the cleaned up URL:", pronoteURL); + + // Retry fetching information with the new URL + const information = await getPronoteInstanceInformation(defaultPawnoteFetcher, { + pronoteURL + }); + + return information + } + catch { + // Show an alert to the user saying that we couldn't + // retrieve the Pronote instance information + // (reason: probably invalid URL) + } +} +``` + +### Explanation of the Implementation + +1. **Initial Attempt :** +The application first attempts to fetch the Pronote instance information using the provided `index-education.net` URL. +2. **Error Handling :** +If the initial attempt fails, the `catch` block is executed. +3. **URL Modification :** +Within the catch block, the application modifies the URL by replacing the domain `index-education.net` with `pronote.toutatice.fr`. +4. **Retry Attempt :** +The application then retries fetching the Pronote instance information using the modified Toutatice URL. +5. **Final Error Handling :** +If the retry attempt also fails, an alert is shown to the user indicating the failure to retrieve Pronote instance information.