From 2d3445b2c93f815cc5ce8783821da2fff770f5f0 Mon Sep 17 00:00:00 2001 From: Thibaud Moustier Date: Sun, 1 Mar 2026 22:04:41 +0100 Subject: [PATCH] Mobile : petit oublie de ma part --- Wallette/mobile/package-lock.json | 33 ++++++++++++++--- Wallette/mobile/package.json | 1 + Wallette/mobile/src/config/env.ts | 33 +++++++++-------- Wallette/mobile/src/screens/AlertsScreen.tsx | 4 +-- Wallette/mobile/src/services/api/http.ts | 37 +++++++++++++++----- Wallette/mobile/src/types/Alert.ts | 25 +++++++++++-- 6 files changed, 99 insertions(+), 34 deletions(-) diff --git a/Wallette/mobile/package-lock.json b/Wallette/mobile/package-lock.json index 6377cc9..6d45584 100644 --- a/Wallette/mobile/package-lock.json +++ b/Wallette/mobile/package-lock.json @@ -12,6 +12,7 @@ "@react-native-async-storage/async-storage": "2.2.0", "@react-navigation/native": "^7.1.28", "@react-navigation/native-stack": "^7.13.0", + "buffer": "^6.0.3", "expo": "~54.0.33", "expo-crypto": "~15.0.8", "expo-notifications": "~0.32.16", @@ -3871,9 +3872,9 @@ } }, "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", @@ -3891,7 +3892,7 @@ "license": "MIT", "dependencies": { "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "ieee754": "^1.2.1" } }, "node_modules/buffer-from": { @@ -9496,6 +9497,30 @@ "node": ">=10" } }, + "node_modules/whatwg-url-without-unicode/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/Wallette/mobile/package.json b/Wallette/mobile/package.json index 813958d..ba7175e 100644 --- a/Wallette/mobile/package.json +++ b/Wallette/mobile/package.json @@ -13,6 +13,7 @@ "@react-native-async-storage/async-storage": "2.2.0", "@react-navigation/native": "^7.1.28", "@react-navigation/native-stack": "^7.13.0", + "buffer": "^6.0.3", "expo": "~54.0.33", "expo-crypto": "~15.0.8", "expo-notifications": "~0.32.16", diff --git a/Wallette/mobile/src/config/env.ts b/Wallette/mobile/src/config/env.ts index 15bff3d..282c6c4 100644 --- a/Wallette/mobile/src/config/env.ts +++ b/Wallette/mobile/src/config/env.ts @@ -3,29 +3,28 @@ import { Platform } from "react-native"; /** * env.ts * ------ - * 1 seul point de config réseau. - * - * IMPORTANT : - * - REST = https://wallette.duckdns.org/api - * - Socket.IO = https://wallette.duckdns.org (PAS /api) - * - * Expo = __DEV__ => on peut forcer PROD pour tester le serveur déployé. + * Source unique de config réseau. */ -// ✅ PROD (duckdns) -const PROD_GATEWAY = "https://wallette.duckdns.org"; +const DEV_LAN_IP = "192.168.129.121"; +const DEV_GATEWAY = `http://${DEV_LAN_IP}:3000`; -// ✅ DEV (pour test Expo sur tel) : force PROD -// Si tu veux revenir au local plus tard : remets ton IP LAN + http://IP:3000 -const DEV_GATEWAY = "https://wallette.duckdns.org"; +const PROD_GATEWAY = "https://wallette.duckdns.org"; export const GATEWAY_BASE_URL = __DEV__ ? DEV_GATEWAY : PROD_GATEWAY; - -// REST (via gateway) export const API_BASE_URL = `${GATEWAY_BASE_URL}/api`; - -// Socket.IO (via gateway) -> RACINE (pas /api) export const SERVER_URL = GATEWAY_BASE_URL; export const ENV_MODE = __DEV__ ? "DEV" : "PROD"; -export const PLATFORM = Platform.OS; \ No newline at end of file +export const PLATFORM = Platform.OS; + +/** + * Basic Auth (protection serveur / NGINX) + * -------------------------------------- + * Sert à passer la barrière d’accès (HTTP 401). + * + * ⚠️ Oui, c’est “dans l’app”. Pour un projet étudiant, c’est acceptable. + * Si vous voulez mieux : variables EAS (secrets) plus tard. + */ +export const BASIC_AUTH_USER = "Thibaud"; +export const BASIC_AUTH_PASS = "ThibaudLCC"; \ No newline at end of file diff --git a/Wallette/mobile/src/screens/AlertsScreen.tsx b/Wallette/mobile/src/screens/AlertsScreen.tsx index dee535c..4d4812d 100644 --- a/Wallette/mobile/src/screens/AlertsScreen.tsx +++ b/Wallette/mobile/src/screens/AlertsScreen.tsx @@ -70,7 +70,7 @@ export default function AlertsScreen() { const filteredSorted = useMemo(() => { const base = - filter === "ALL" ? items : items.filter((a) => (a.alertLevel ?? "INFO") === filter); + filter === "ALL" ? items : items.filter((a) => ((a.alertLevel ?? a.criticality ?? "INFO") === filter)); return [...base].sort((a, b) => { const r = severityRank(b.alertLevel) - severityRank(a.alertLevel); @@ -168,7 +168,7 @@ export default function AlertsScreen() { - {item.alertLevel ?? "INFO"} + {item.alertLevel ?? item.criticality ?? "INFO"} diff --git a/Wallette/mobile/src/services/api/http.ts b/Wallette/mobile/src/services/api/http.ts index 6814903..a7f5106 100644 --- a/Wallette/mobile/src/services/api/http.ts +++ b/Wallette/mobile/src/services/api/http.ts @@ -1,13 +1,25 @@ import { API_BASE_URL } from "../../config/env"; +import { BASIC_AUTH_USER, BASIC_AUTH_PASS } from "../../config/env"; +import { Buffer } from "buffer"; /** * HTTP helper (fetch) * ------------------- - * Compatible avec 2 formats : - * A) "wrap" : { ok:true, data: ... } / { ok:false, error:{message} } - * B) "raw" : { ... } / Alert[] etc. + * - Ajoute Basic Auth si configuré (pour passer la barrière 401) + * - Compatible avec 2 formats : + * A) wrap : { ok:true, data: ... } / { ok:false, error:{message} } + * B) raw : { ... } / [...] */ +function getBasicAuthHeader(): string | null { + const u = (BASIC_AUTH_USER ?? "").trim(); + const p = (BASIC_AUTH_PASS ?? "").trim(); + if (!u || !p) return null; + + const token = Buffer.from(`${u}:${p}`, "utf8").toString("base64"); + return `Basic ${token}`; +} + async function parseJsonSafe(res: Response) { const text = await res.text(); try { @@ -31,10 +43,22 @@ function unwrapOrRaw(json: any): T { return json as T; } +function buildHeaders(extra?: Record) { + const headers: Record = { + Accept: "application/json", + ...(extra ?? {}), + }; + + const auth = getBasicAuthHeader(); + if (auth) headers.Authorization = auth; + + return headers; +} + export async function apiGet(path: string): Promise { const res = await fetch(buildUrl(path), { method: "GET", - headers: { Accept: "application/json" }, + headers: buildHeaders(), }); const json = await parseJsonSafe(res); @@ -50,10 +74,7 @@ export async function apiGet(path: string): Promise { export async function apiPost(path: string, body: unknown): Promise { const res = await fetch(buildUrl(path), { method: "POST", - headers: { - Accept: "application/json", - "Content-Type": "application/json", - }, + headers: buildHeaders({ "Content-Type": "application/json" }), body: JSON.stringify(body), }); diff --git a/Wallette/mobile/src/types/Alert.ts b/Wallette/mobile/src/types/Alert.ts index d1b7caa..4a7a405 100644 --- a/Wallette/mobile/src/types/Alert.ts +++ b/Wallette/mobile/src/types/Alert.ts @@ -1,16 +1,35 @@ +/** + * Alert.ts + * -------- + * Format d'alerte utilisé par : + * - Socket.IO (event "alert") + * - REST : GET /api/alerts/events?userId=...&limit=... + * + * Le backend peut envoyer : + * - alertLevel (ancien) + * - OU criticality (nouveau BotService) + * + * On accepte les deux. + */ + export type AlertLevel = "CRITICAL" | "WARNING" | "INFO"; export type AlertAction = "BUY" | "SELL" | "HOLD" | "STOP_LOSS"; export interface Alert { action?: AlertAction; pair?: string; - confidence?: number; + confidence?: number; // 0..1 reason?: string; - // compat web + // compat: certains front/back utilisent 'message' message?: string; + // ancien nom alertLevel?: AlertLevel; - timestamp?: number; + + // nouveau nom (BotService) + criticality?: AlertLevel; + + timestamp?: number; // ms price?: number; } \ No newline at end of file -- 2.50.1