@mostajs/wagon-engine 0.4.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +6 -0
- package/llms.txt +25 -4
- package/package.json +3 -3
- package/src/demarrer.mjs +4 -2
- package/src/wagon.mjs +42 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,34 @@
|
|
|
3
3
|
**Auteur** : Dr Hamid MADANI <drmdh@msn.com>
|
|
4
4
|
Format : Keep a Changelog ; versions : SemVer.
|
|
5
5
|
|
|
6
|
+
## [0.6.0] — 2026-10-28
|
|
7
|
+
|
|
8
|
+
### Ajouté
|
|
9
|
+
- **Le vendeur de chaque devise** (`@mostajs/payment` ≥ 2.7) : `PAIEMENT_VENDEUR_<DEVISE>` dans le `.env`. Dès qu'une
|
|
10
|
+
telle variable est déclarée, une devise sans vendeur nommé n'est pas vendue : Stripe et les banques prépayées de
|
|
11
|
+
cette devise sont écartés, même avec leurs clés (un avertissement le dit au démarrage). `{{VENDEUR}}` des textes
|
|
12
|
+
légaux nomme le vendeur de chaque devise vendue, une ligne par devise ; `config.legal.VENDEUR` l'emporte s'il est
|
|
13
|
+
posé. `PAIEMENT_STRIPE_DEVISES` dit la devise de Stripe (défaut EUR), reprise par l'affichage des prix. Sans aucune
|
|
14
|
+
`PAIEMENT_VENDEUR_*`, rien ne change. Essai T-ENG-14.
|
|
15
|
+
- `creerWagon(…).moyens` : les moyens réellement proposés ; `demarrer` le rend tel quel.
|
|
16
|
+
- `llms.txt` et le README s'ouvrent sur la configuration du `.env` par `@mostajs/config` (chargement, cascade
|
|
17
|
+
`MOSTA_ENV`, valeur vide, priorité de l'environnement).
|
|
18
|
+
|
|
19
|
+
### Dépendances
|
|
20
|
+
- `@mostajs/payment` ^2.7.0.
|
|
21
|
+
|
|
22
|
+
## [0.5.0] — 2026-10-28
|
|
23
|
+
|
|
24
|
+
### Ajouté
|
|
25
|
+
- **`config.cadreWagon`** : le cadre des pages du moteur (tarifs, inscription, connexion, aide, à propos, compte,
|
|
26
|
+
déconnexion), par exemple `{ disposition: 'application', application: { retour: '/', langues: true } }`. Une greffe
|
|
27
|
+
qui vit dans la disposition « application » n'y renvoie plus la vitrine et son menu commun à tous les publics. Une
|
|
28
|
+
page de la charge qui choisit son cadre le garde. Essai T-ENG-13.
|
|
29
|
+
|
|
30
|
+
### Corrigé
|
|
31
|
+
- **Le pied de page ne liste que les textes légaux servis** (`legaux`, `@mostajs/wagon-ui` ≥ 0.11) : un texte incomplet
|
|
32
|
+
n'était pas servi (0.4) mais restait lié, d'où un 404 sur chaque page. Essai T-ENG-12.
|
|
33
|
+
|
|
6
34
|
## [0.4.1] — 2026-10-28
|
|
7
35
|
|
|
8
36
|
### Corrigé
|
package/README.md
CHANGED
|
@@ -41,6 +41,12 @@ await demarrer({ config, charge });
|
|
|
41
41
|
| `CHARGILY_SECRET_KEY` · `SATIM_MERCHANT_ID`, `SATIM_PASSWORD`, `SATIM_TERMINAL_ID` · `PAYPAL_…` | les banques prépayées proposées par `config.paiement.prepaye` |
|
|
42
42
|
| `PAIEMENT_STRIPE=off`, `PAIEMENT_CHARGILY=off`, `PAIEMENT_SATIM=off`, `PAIEMENT_PAYPAL=off` | **coupe un moyen** sans toucher à ses clés |
|
|
43
43
|
| `WAGON_ADMINS` | les courriels administrateurs (confirmés par un code reçu) |
|
|
44
|
+
| `PAIEMENT_VENDEUR_DZD`, `PAIEMENT_VENDEUR_EUR`… | 0.6 — **le vendeur de chaque devise** (dénomination, forme, adresse, immatriculations) ; dès qu'une est déclarée, une devise sans vendeur n'est pas vendue, et `{{VENDEUR}}` des CGV les nomme |
|
|
45
|
+
| `PAIEMENT_STRIPE_DEVISES` | 0.6 — la devise de Stripe (défaut `EUR`) |
|
|
46
|
+
|
|
47
|
+
**Le `.env` d'abord.** Toutes les clés passent par `getEnv` de `@mostajs/config` : cascade `MOSTA_ENV` (`PROD_CLÉ` l'emporte sur `CLÉ`), valeur vide = absente, et `loadEnv` n'écrase jamais une variable déjà posée par l'orchestrateur. Si `wagon.config.mjs` lit des variables, il appelle `loadEnv` lui-même, en tête.
|
|
48
|
+
|
|
49
|
+
**Un vendeur par devise (0.6).** Un SaaS qui vend en dinars par un auto-entrepreneur et en euros par une société pose `PAIEMENT_VENDEUR_DZD=…` et `PAIEMENT_VENDEUR_EUR=…`. Une devise déclarée vide (`PAIEMENT_VENDEUR_EUR=`, la société n'est pas encore immatriculée) n'est pas vendue : Stripe est écarté même avec sa clé. Sans aucune `PAIEMENT_VENDEUR_*`, rien ne change.
|
|
44
50
|
|
|
45
51
|
**Le paiement est au choix de l'utilisateur**, parmi les moyens actifs. Un moyen est actif quand ses clés sont dans le `.env` et que son commutateur n'est pas sur `off`. Une banque prépayée doit en plus être proposée par la configuration.
|
|
46
52
|
|
package/llms.txt
CHANGED
|
@@ -4,13 +4,28 @@
|
|
|
4
4
|
> PayPal), espace client, administration, pages légales, robots/sitemap, sauvegarde, fr/en/ar. Une GREFFE n'apporte que
|
|
5
5
|
> wagon.config.mjs, charge/, legal/ et son .env. N2 (pack). Extrait du gabarit mosta-wagon 0.11.0 le 26/10/2026.
|
|
6
6
|
|
|
7
|
-
- Version: 0.
|
|
7
|
+
- Version: 0.6.0 · Licence: AGPL-3.0-or-later · Auteur: Dr Hamid MADANI <drmdh@msn.com>
|
|
8
8
|
- Chemin: mostajs/mosta-platform-stack/mosta-wagon-engine · gabarit d'une greffe : Entreprise/mosta-wagon
|
|
9
9
|
|
|
10
|
+
## ⚙️ D'EMBLÉE : LE .env ET LA CASCADE @mostajs/config
|
|
11
|
+
Une greffe se configure par SON `.env` (dossier courant de `demarrer`, ou `racine`). Avant tout :
|
|
12
|
+
1. **Qui le charge** : `demarrer` appelle `loadEnv({ path: <racine>/.env })` de `@mostajs/config`. Si `wagon.config.mjs`
|
|
13
|
+
lit lui-même des variables (getEnv au chargement du module), il doit appeler `loadEnv` EN TÊTE, avant de les lire :
|
|
14
|
+
`import { loadEnv, getEnv } from '@mostajs/config'; loadEnv({ path: join(process.cwd(), '.env') });`
|
|
15
|
+
Le second appel (celui de demarrer) n'écrase rien.
|
|
16
|
+
2. **loadEnv ne SURCHARGE pas** une variable déjà dans l'environnement : la valeur de l'orchestrateur (pm2, systemd,
|
|
17
|
+
conteneur) prime sur le fichier.
|
|
18
|
+
3. **Cascade** (première valeur NON VIDE) : `${MOSTA_ENV}_${CLÉ}` → `${CLÉ}` → défaut. Un seul .env, des profils
|
|
19
|
+
`TEST_`/`DEV_`/`PROD_`. Toutes les clés ci-dessous, et celles de `@mostajs/payment`, passent par `getEnv`.
|
|
20
|
+
4. **Vide = absent** : `WAGON_STRIPE_SECRET_KEY=` ne configure rien. Exception voulue : `PAIEMENT_VENDEUR_<DEVISE>=`
|
|
21
|
+
vide DÉCLARE la devise sans la nommer (elle n'est pas vendue).
|
|
22
|
+
5. Les secrets et les informations de l'entreprise sont posés par l'exploitant sur le serveur, jamais commités ;
|
|
23
|
+
`.env.example` de la greffe liste chaque clé, sans valeur.
|
|
24
|
+
|
|
10
25
|
## EXPORTS
|
|
11
|
-
- demarrer({ config, charge, racine = cwd, journal }) → { wagon, serveur, moyens: string[], fermer() }
|
|
26
|
+
- demarrer({ config, charge, racine = cwd, journal }) → { wagon, serveur, moyens: string[], fermer() } (moyens = wagon.moyens, 0.6)
|
|
12
27
|
- creerWagon({ config, charge, sgbd: string|{dialect,uri}, baseUrl, stripe?, webhookSecret?, transport?, journal?,
|
|
13
|
-
paiement?: { banques: { chargily:'DZD', … }, port? }, racine? }) → { handler, catalogue(), catalogueStripe(), fermer(), … }
|
|
28
|
+
paiement?: { banques: { chargily:'DZD', … }, port?, deviseStripe? }, racine? }) → { moyens, handler, catalogue(), catalogueStripe(), fermer(), … }
|
|
14
29
|
- schemasWagon() (sauvegarde) · sauvegarder({ cibles, driver, seau, recipients, garder }) · suivrePalette(…)
|
|
15
30
|
- '@mostajs/wagon-engine/conformite' = src/conformite/conformite.test.mjs (suite mjs-unit, juge WAGON_GREFFE ou cwd)
|
|
16
31
|
|
|
@@ -19,7 +34,13 @@ PORT, HOST · WAGON_BASE_URL · WAGON_DB_DIALECT (sqlite|postgres…), WAGON_SGB
|
|
|
19
34
|
WAGON_EMAIL_FROM (ou WAGON_COURRIEL_FICHIER pour les essais) · WAGON_STRIPE_SECRET_KEY|RESTRICTED_KEY, WAGON_STRIPE_WEBHOOK_SECRET ·
|
|
20
35
|
CHARGILY_SECRET_KEY|API_KEY · SATIM_MERCHANT_ID, SATIM_PASSWORD, SATIM_TERMINAL_ID · PAYPAL_CLIENT_ID, PAYPAL_SECRET,
|
|
21
36
|
PAYPAL_WEBHOOK_ID · PAIEMENT_<STRIPE|CHARGILY|SATIM|PAYPAL>=off (coupe le moyen) · WAGON_ADMINS · WAGON_INDEXER.
|
|
22
|
-
|
|
37
|
+
0.6 (@mostajs/payment ≥ 2.7) : PAIEMENT_VENDEUR_<DEVISE> (le vendeur de cette devise : dénomination, forme, adresse,
|
|
38
|
+
immatriculations) · PAIEMENT_STRIPE_DEVISES (la devise de Stripe, défaut EUR).
|
|
39
|
+
Moyen ACTIF = clés présentes ET commutateur ≠ off (ET, pour une banque prépayée, proposée par config.paiement.prepaye)
|
|
40
|
+
ET, 0.6, dès qu'une PAIEMENT_VENDEUR_* est déclarée, un vendeur NOMMÉ pour sa devise. `{{VENDEUR}}` des textes légaux
|
|
41
|
+
nomme alors le vendeur de chaque devise vendue (une ligne par devise, nom de la devise dans la langue de la page) ;
|
|
42
|
+
`config.legal.VENDEUR` l'emporte s'il est posé. Exemple : dinars par un auto-entrepreneur, euros par une société pas
|
|
43
|
+
encore immatriculée → `PAIEMENT_VENDEUR_DZD=…`, `PAIEMENT_VENDEUR_EUR=` (vide) : seule la vente en dinars s'ouvre.
|
|
23
44
|
|
|
24
45
|
## CONTRAT DE LA CHARGE (charge/index.mjs)
|
|
25
46
|
liens · ressources (quota { cle, limite, periode } | plafond { cle, limite, plafond: true }) · accueil (fiche { fr: { titre, lede, actions, preuves } }, ou 0.3 : async (ctx) => ({ titre, contenu, disposition, application, console })) · dispositions (0.3 : { nom: (p) => corps }) · textes ·
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mostajs/wagon-engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Le wagon d'un SaaS, une fois pour toutes : comptes, connexion, paliers, quotas, paiement (Stripe, Chargily, SATIM), espace client, administration, pages légales, fr/en/ar. Une greffe n'apporte que wagon.config.mjs, charge/, legal/ et son .env ; la suite de conformité publiée juge la greffe.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mostajs",
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"@mostajs/mailer": "^0.2.0",
|
|
51
51
|
"@mostajs/markdown-html": "^0.3.0",
|
|
52
52
|
"@mostajs/orm": "^2.12.1",
|
|
53
|
-
"@mostajs/payment": "^2.
|
|
53
|
+
"@mostajs/payment": "^2.7.0",
|
|
54
54
|
"@mostajs/subscriptions-plan": "^0.9.0",
|
|
55
|
-
"@mostajs/wagon-ui": "^0.
|
|
55
|
+
"@mostajs/wagon-ui": "^0.11.0",
|
|
56
56
|
"better-sqlite3": "^12.11.1",
|
|
57
57
|
"stripe": "^17.7.0"
|
|
58
58
|
},
|
package/src/demarrer.mjs
CHANGED
|
@@ -11,6 +11,7 @@ import { createServer } from 'node:http';
|
|
|
11
11
|
import { appendFileSync } from 'node:fs';
|
|
12
12
|
import { join } from 'node:path';
|
|
13
13
|
import { loadEnv, getEnv } from '@mostajs/config';
|
|
14
|
+
import { devisesDuMoyen } from '@mostajs/payment/server';
|
|
14
15
|
import { creerWagon } from './wagon.mjs';
|
|
15
16
|
|
|
16
17
|
const coupe = (moyen) => getEnv(`PAIEMENT_${moyen.toUpperCase()}`, '') === 'off';
|
|
@@ -53,10 +54,11 @@ export async function demarrer({ config, charge, racine = process.cwd(), journal
|
|
|
53
54
|
stripe: cle ? new (await import('stripe')).default(cle) : null,
|
|
54
55
|
webhookSecret: getEnv('WAGON_STRIPE_WEBHOOK_SECRET', ''),
|
|
55
56
|
transport: await transport(),
|
|
56
|
-
|
|
57
|
+
// 0.6 — la devise de Stripe (PAIEMENT_STRIPE_DEVISES, défaut EUR) : creerWagon écarte une devise sans vendeur.
|
|
58
|
+
paiement: { banques, deviseStripe: devisesDuMoyen('stripe', ['EUR'])[0] },
|
|
57
59
|
});
|
|
58
60
|
await wagon.catalogue();
|
|
59
|
-
const moyens =
|
|
61
|
+
const moyens = wagon.moyens;
|
|
60
62
|
const serveur = createServer(wagon.handler);
|
|
61
63
|
const port = Number(getEnv('PORT', '4800'));
|
|
62
64
|
await new Promise((ok) => serveur.listen(port, getEnv('HOST', '127.0.0.1'), ok));
|
package/src/wagon.mjs
CHANGED
|
@@ -25,6 +25,7 @@ import { creerWagonUi, esc } from '@mostajs/wagon-ui';
|
|
|
25
25
|
import { creerComptes, schemasComptes } from '@mostajs/comptes';
|
|
26
26
|
import { createBilling, createStripeSale, createPrepaidSale, billingSchemas, checkLimits, assertMonotonicPlans } from '@mostajs/subscriptions-plan/server';
|
|
27
27
|
import { PaymentSchema } from '@mostajs/payment';
|
|
28
|
+
import { venteAutorisee, vendeursFromEnv } from '@mostajs/payment/server';
|
|
28
29
|
import { formatNumber, resolveFormatLocale } from '@mostajs/i18n';
|
|
29
30
|
import { createPasswordAuth, createEmailCodeAuth, SessionSchema, ipClient, memoryLimiter } from '@mostajs/auth-lite';
|
|
30
31
|
import { emailCodeEmailHtml, emailCodeEmailText, emailCodeForm, emailLinkConfirmPage, AUTH_CSS } from '@mostajs/auth-ui';
|
|
@@ -165,12 +166,18 @@ const cookieDe = (req, nom) => (req.headers.cookie || '').split(';').map((s) =>
|
|
|
165
166
|
* @param {{ envoyer: Function } | null} [o.transport] les courriels (code de connexion)
|
|
166
167
|
* @param {{ banques?: Record<string, string>, port?: object }} [o.paiement] 0.3 — vente prépayée : les banques ACTIVES
|
|
167
168
|
* et leur devise (`{ chargily: 'DZD', paypal: 'EUR' }`, server.mjs ne garde que celles dont le .env porte les
|
|
168
|
-
* clés) ; `port` remplace @mostajs/payment (essais)
|
|
169
|
+
* clés) ; `port` remplace @mostajs/payment (essais) ; 0.6 — `deviseStripe` (défaut 'EUR') : la devise de Stripe
|
|
170
|
+
* 0.6 — une devise sans VENDEUR (`PAIEMENT_VENDEUR_<DEVISE>`, @mostajs/payment ≥ 2.7, règle en vigueur dès qu'une telle
|
|
171
|
+
* variable est déclarée) n'est pas vendue : Stripe et les banques de cette devise sont écartés ici, et `{{VENDEUR}}`
|
|
172
|
+
* des textes légaux nomme le vendeur de chaque devise vendue.
|
|
169
173
|
*/
|
|
170
174
|
/** 0.5 — le commit en service (posé par le déployeur dans le dossier de l'instance) et l'heure de démarrage. */
|
|
171
175
|
const lireRevision = (racine) => { try { return readFileSync(join(racine, 'REVISION'), 'utf8').trim() || null; } catch { return null; } };
|
|
172
176
|
export async function creerWagon({ config, charge, sgbd, baseUrl, stripe = null, webhookSecret = '', transport = null, journal = console, paiement = null, racine = process.cwd() }) {
|
|
173
177
|
const origine = String(baseUrl || '').replace(/\/$/, '');
|
|
178
|
+
// 0.6 — pas de vente dans une devise sans vendeur (même si les clés de sa banque sont posées).
|
|
179
|
+
const deviseStripe = String(paiement?.deviseStripe ?? 'EUR').toUpperCase();
|
|
180
|
+
if (stripe && !venteAutorisee(deviseStripe)) { journal.warn(`wagon : Stripe écarté — aucun vendeur pour ${deviseStripe} (PAIEMENT_VENDEUR_${deviseStripe})`); stripe = null; }
|
|
174
181
|
const REVISION = lireRevision(racine); const DEMARRE_LE = new Date().toISOString();
|
|
175
182
|
const https = /^https:/.test(origine);
|
|
176
183
|
const S = Object.fromEntries(schemasWagon().map((s) => [s.name, s]));
|
|
@@ -226,7 +233,11 @@ export async function creerWagon({ config, charge, sgbd, baseUrl, stripe = null,
|
|
|
226
233
|
accountOf: async (c) => (await d.findOne(S.Account, { stripeCustomerId: c }))?.id ?? null,
|
|
227
234
|
},
|
|
228
235
|
}) : null;
|
|
229
|
-
const banques =
|
|
236
|
+
const banques = Object.fromEntries(Object.entries(paiement?.banques ?? {}).filter(([b, dv]) => {
|
|
237
|
+
if (venteAutorisee(String(dv))) return true;
|
|
238
|
+
journal.warn(`wagon : ${b} écarté — aucun vendeur pour ${String(dv).toUpperCase()} (PAIEMENT_VENDEUR_${String(dv).toUpperCase()})`);
|
|
239
|
+
return false;
|
|
240
|
+
}));
|
|
230
241
|
const prepaye = Object.keys(banques).length ? createPrepaidSale({
|
|
231
242
|
billing: facturation, providers: banques, payment: paiement?.port, metadataKeys: { account: META.account, plan: META.plan, period: 'wagon_periode' },
|
|
232
243
|
// 0.10 — `return` : SATIM ne notifie pas le serveur, il renvoie l'acheteur (@mostajs/payment ≥ 2.6). Les banques à
|
|
@@ -329,12 +340,26 @@ export async function creerWagon({ config, charge, sgbd, baseUrl, stripe = null,
|
|
|
329
340
|
*/
|
|
330
341
|
const NOMS_MOYENS = { stripe: 'Stripe (carte bancaire)', chargily: 'Chargily (CIB, Edahabia)', paypal: 'PayPal', satim: 'SATIM (CIB)' };
|
|
331
342
|
const signales = new Set();
|
|
343
|
+
/**
|
|
344
|
+
* 0.6 — `{{VENDEUR}}` : le vendeur de chaque devise VENDUE (Stripe et les banques actives), d'après
|
|
345
|
+
* `PAIEMENT_VENDEUR_<DEVISE>` ; une ligne par devise. Vide si aucune n'a de vendeur : le texte n'est alors pas servi.
|
|
346
|
+
*/
|
|
347
|
+
function vendeurLegal(lang) {
|
|
348
|
+
const vendeurs = vendeursFromEnv();
|
|
349
|
+
const parDevise = new Map(stripe ? [[deviseStripe, ['stripe']]] : []);
|
|
350
|
+
for (const [b, dv] of Object.entries(banques)) { const k = String(dv).toUpperCase(); parDevise.set(k, [...(parDevise.get(k) ?? []), b]); }
|
|
351
|
+
let noms = null; try { noms = new Intl.DisplayNames([lang, 'fr'], { type: 'currency' }); } catch { /* langue inconnue */ }
|
|
352
|
+
return [...parDevise].filter(([dv]) => vendeurs[dv]).map(([dv, ms]) => {
|
|
353
|
+
const n = noms?.of(dv) ?? dv;
|
|
354
|
+
return `- **${n.charAt(0).toUpperCase()}${n.slice(1)} (${dv})** — ${ms.map((m) => NOMS_MOYENS[m] ?? m).join(', ')} : ${vendeurs[dv]}`;
|
|
355
|
+
}).join('\n');
|
|
356
|
+
}
|
|
332
357
|
function documentLegal(doc, lang) {
|
|
333
358
|
const dossier = config.dossierLegal ?? join(racine, 'legal'); // la greffe, plus le moteur
|
|
334
359
|
const f = [lang, 'fr'].map((l) => join(dossier, `${doc}.${l}.md`)).find((x) => existsSync(x));
|
|
335
360
|
if (!f) return { html: '', complet: false };
|
|
336
361
|
const moyens = [...(stripe ? ['stripe'] : []), ...Object.keys(paiement?.banques ?? {})].map((m) => NOMS_MOYENS[m] ?? m).join(', ');
|
|
337
|
-
const valeurs = { SERVICE: config.marque.nom, DOMAINE: origine.replace(/^https?:\/\//, ''), CONTACT_EMAIL: config.marque.courriel ?? '', PAIEMENT: moyens, ...(config.legal ?? {}) };
|
|
362
|
+
const valeurs = { SERVICE: config.marque.nom, DOMAINE: origine.replace(/^https?:\/\//, ''), CONTACT_EMAIL: config.marque.courriel ?? '', PAIEMENT: moyens, VENDEUR: vendeurLegal(lang), ...(config.legal ?? {}) };
|
|
338
363
|
const manquants = new Set();
|
|
339
364
|
const texte = readFileSync(f, 'utf8').replace(/\{\{(\w+)\}\}/g, (m, k) => { if (valeurs[k]) return String(valeurs[k]); manquants.add(k); return ''; });
|
|
340
365
|
const aTrancher = /⚖️|À FAIRE TRANCHER/.test(texte);
|
|
@@ -347,6 +372,14 @@ export async function creerWagon({ config, charge, sgbd, baseUrl, stripe = null,
|
|
|
347
372
|
return { html: complet ? mdToHtml(texte).html : '', complet };
|
|
348
373
|
}
|
|
349
374
|
|
|
375
|
+
/** 0.5 — les textes légaux servis dans une langue (lus une fois : ils ne changent qu'au redéploiement). */
|
|
376
|
+
const LEGAUX = ['mentions-legales', 'cgu', 'cgv', 'confidentialite'];
|
|
377
|
+
const servis = new Map();
|
|
378
|
+
const legauxServis = (lang) => {
|
|
379
|
+
if (!servis.has(lang)) servis.set(lang, LEGAUX.filter((doc) => documentLegal(doc, lang).complet));
|
|
380
|
+
return servis.get(lang);
|
|
381
|
+
};
|
|
382
|
+
|
|
350
383
|
async function vueEspace(compte) {
|
|
351
384
|
const actif = await facturation.activePlan(String(compte.id));
|
|
352
385
|
const quotas = {};
|
|
@@ -413,7 +446,9 @@ export async function creerWagon({ config, charge, sgbd, baseUrl, stripe = null,
|
|
|
413
446
|
const qui = s ? await comptes.qui(String(s.user ?? s.userId ?? '')) : null;
|
|
414
447
|
const estAdmin = !!(qui && await estAdministrateur(qui.utilisateur.courriel));
|
|
415
448
|
// 0.5 — `chemin` : la page réelle (canonique, liens de langue) ; `actif` reste l'onglet (wagon-ui 0.5.1).
|
|
416
|
-
|
|
449
|
+
// 0.5 — le pied de page ne liste que les textes légaux SERVIS (un lien vers un texte incomplet menait à un 404) ;
|
|
450
|
+
// `config.cadreWagon` donne le cadre des pages du moteur (une page de la charge qui choisit le sien le garde).
|
|
451
|
+
const page = (o) => ui.page({ lang, connecte: !!qui, base: origine, chemin, legaux: legauxServis(lang), ...(config.cadreWagon ?? {}), ...o });
|
|
417
452
|
const ouvrirSession = async (userId, vers = '/compte') => rediriger(vers, { 'set-cookie': cookieStrict('wagon_session', await sessions.ouvrir(userId), { maxAge: 30 * 86400, https }) });
|
|
418
453
|
|
|
419
454
|
// 0.5 — la santé : le commit EN SERVICE (fichier REVISION posé par le déployeur) et l'heure de démarrage.
|
|
@@ -608,7 +643,7 @@ export async function creerWagon({ config, charge, sgbd, baseUrl, stripe = null,
|
|
|
608
643
|
if (!p) return null;
|
|
609
644
|
const pp = typeof p.prepaid === 'string' ? JSON.parse(p.prepaid || 'null') : p.prepaid;
|
|
610
645
|
const l = [...new Set(Object.values(banques))].filter((dv) => Number(pp?.[dv]?.month) > 0).map((dv) => ({ centimes: Number(pp[dv].month), devise: dv }));
|
|
611
|
-
if (stripe && Number(p.price) > 0) l.push({ centimes: Number(p.price), devise:
|
|
646
|
+
if (stripe && Number(p.price) > 0) l.push({ centimes: Number(p.price), devise: deviseStripe });
|
|
612
647
|
return l.length ? l : null;
|
|
613
648
|
};
|
|
614
649
|
const suite = suiteSure(url.searchParams.get('suite'));
|
|
@@ -884,6 +919,8 @@ export async function creerWagon({ config, charge, sgbd, baseUrl, stripe = null,
|
|
|
884
919
|
}
|
|
885
920
|
|
|
886
921
|
return {
|
|
922
|
+
// 0.6 — les moyens réellement proposés (après le contrôle du vendeur de chaque devise)
|
|
923
|
+
moyens: [...(stripe ? ['stripe'] : []), ...Object.keys(banques)],
|
|
887
924
|
handler: (req, res) => handler(req, res).catch((e) => { journal.error(e); if (!res.headersSent) { res.writeHead(500, { 'content-type': 'text/plain; charset=utf-8' }); res.end('Erreur interne'); } }),
|
|
888
925
|
catalogue, catalogueStripe, dialect: d, schemas: S, comptes, facturation, confirmerAdmin, reprendrePaiements,
|
|
889
926
|
/** Fixe le mot de passe d'un compte depuis le serveur (mot de passe perdu) ; lève si la règle le refuse. */
|