une application mettant en œuvre une prise de contact entre un demandeur de services et son éventuel prestataire associé.
  • C# 41%
  • JavaScript 31.1%
  • HTML 10.4%
  • SCSS 6.1%
  • Less 5%
  • Other 6.3%
Find a file
Paul Schneider d62e59ba30 postit: trailing-slash regression + loopback browser cleanup; identityserver: BC cert loader + SecurityKey
PostIt
- LoginPage renders StatusMessage as a read-only TextBox so the
  text is mouse-selectable and copyable (no copy button).
- LoginPageViewModel exposes ExternalUrl (Authentication.Authority
  with trailing slash stripped) and DiscoveryUrl
  (ExternalUrl + '/.well-known/openid-configuration'). LoginAsync
  surfaces the discovery URL before the call and suffixes it onto
  every error message, so reachability issues are diagnosable by
  pasting the URL into a browser.
- LoopbackBrowser (used for the OIDC redirect listener on desktop)
  now bounds the GetContextAsync wait at 5 minutes and calls both
  Stop() and Close() in the finally, so the listener is always
  released even if the user abandons the flow. Without this, the
  next PostIt launch fails with 'Failed to listen on prefix
  http://127.0.0.1:7890/ because it conflicts with an existing
  registration on the machine.'
- Add LoginPageViewModelTests.LoginAsync_works_when_authority_has_trailing_slash
  to lock in the discovery URL contract.
- Add LoopbackBrowserTests covering both timeout and happy-path
  listener cleanup.

Yavsc.Org
- Drop the CustomEntries['jwks_uri'] override from commit 84160f07.
  IdentityServer8 reserves that key and rejects the override with
  'Discovery custom entry jwks_uri cannot be added, because it
  already exists.' The default /.well-known/openid-configuration/jwks
  endpoint is what DiscoveryKeyEndpoint actually serves.
- Replace X509Certificate2.CreateFromPemFile + the 3-arg
  X509Certificate2(path, key, X509KeyStorageFlags) ctor with a
  BouncyCastle-backed loader. The BCL path raised
  InvalidOperationException during AddSigningCredential and aborted
  the runtime with SIGABRT (code=6/ABRT, libcoreclr.so stack) on
  the production EC Let's Encrypt cert. BouncyCastle 2.6.2
  PemReader accepts PKCS#1 + PKCS#8 EC/RSA PEMs uniformly; RSA
  path uses DotNetUtilities.ToRSA, EC path rebuilds ECDsa from
  ECParameters with the curve dispatched by NIST order bit length
  (256/384/521).
- Switch the signing credential handed to IdentityServer8 from
  X509Certificate2 to a SigningCredentials built from a SecurityKey
  (RsaSecurityKey / ECDsaSecurityKey). The cert loaded fine but
  IdentityServer8's key material service reads cert.PrivateKey at
  runtime — on Linux that handle is not retained across the
  X509Certificate2 / runtime boundary, so CreateJwkDocumentAsync
  raised NullReferenceException on the first GET /jwks. The
  SecurityKey is a pure managed object whose Key is a live
  AsymmetricAlgorithm, which survives every read IdentityServer
  does.
- Add BouncyCastle.Cryptography 2.6.2 to src/Yavsc.Org/Yavsc.Org.csproj
  and the matching PackageVersion in Directory.Packages props.
- Wrap the loader in a try/catch that prints the full managed
  stack to stderr on failure, so future PEM-format issues surface
  in journalctl instead of being hidden behind SIGABRT.
2026-06-21 07:36:22 +01:00
.forgejo/workflows Dockerfile & actions 2026-02-02 00:39:24 +00:00
.github Bump the all-actions group with 4 updates 2026-06-11 19:22:08 +00:00
.vscode refactoring the login 2026-06-20 15:01:03 +01:00
assets allow_failure: true 2021-06-07 01:33:04 +01:00
contrib deploying the blogs 2026-06-19 23:09:43 +01:00
doc doc cleanup 2026-06-20 19:00:10 +01:00
src postit: trailing-slash regression + loopback browser cleanup; identityserver: BC cert loader + SecurityKey 2026-06-21 07:36:22 +01:00
.dockerignore cleanup 2026-06-07 07:32:24 +01:00
.editorconfig refact 2026-06-20 19:51:22 +01:00
.env.sample do not override appsettings-*.*.json 2026-06-19 16:18:39 +01:00
.eslintrc.json cs requires uname 2017-03-17 22:42:50 +01:00
.gitattributes a default attr set from GitHub 2017-07-12 12:12:39 +02:00
.gitignore publish postit settings 2026-06-20 18:46:05 +01:00
.jshintrc initial 2019-09-08 01:36:45 +01:00
Directory.Build.props refact & cookies 2026-02-17 19:24:30 +00:00
Directory.Packages.props Split Directory.Packages.props: shared versions in root, per-product in src/ 2026-06-19 18:51:18 +01:00
docker-compose.yaml docker composes 2026-05-30 15:41:59 +01:00
Dockerfile Test reorg 2026-06-19 20:07:05 +01:00
Dockerfile.backend Broken action 2026-06-19 23:12:17 +01:00
dotnet-tools.json a scoring model 2026-05-24 19:35:35 +01:00
esbuild.config.mjs refac: load jQuery + Bootstrap as global scripts in _Layout 2026-06-14 15:16:16 +01:00
INSTALL.md docs: add npm install + build:js to install procedure 2026-06-14 14:11:59 +01:00
LICENSE Licence WTFPL 2025-02-24 21:26:21 +00:00
Makefile Regenerate the secret 2026-06-19 01:36:08 +01:00
package.json refac: separate front assets into esbuild bundles 2026-06-14 14:11:33 +01:00
README.md README: mark appsettings-org.Development.json as gitignored 2026-06-20 18:20:38 +01:00
ROADMAP.md refactoring 2026-06-19 19:59:15 +01:00
TODO.fr.md.archive docs: roadmap à jour, archive TODO.fr, session DDD + droits yavsc 2026-06-14 12:17:03 +01:00
yavsc.sln Relocate test project: test/yavscTests -> src/Yavsc.Org.Tests 2026-06-19 17:52:54 +01:00

Yavsc

C'est une application mettant en oeuvre une prise de contact entre un demandeur de services et son éventuel prestataire associé.

Statut actuel des actions GitHub

  • Build and Push Yavsc Apk

  • Build and Push Yavsc Production Image

Construction et déploiement

Construction

 dotnet build

et, pour execution en environment de développement

~/workspace/yavsc/Yavsc @ ASPNETCORE_ENV=Development dotnet run

Tests

Utilisez GNU/Makefile (et visitez le code, dans le dossier test ):

[TODO] Depuis le répertoire racine:

make test

Installation / Déploient / Développement

les services et l'API

La Prod

cd srv/Yavsc : make pushInProd CONFIGURATION=Release.

puis, pour une première installation make install_service.

Fonctionnalités (encore en cours de développement)

Elle est censée aboutir à une prise commande, un payement du client, à une collecte du retour du client, et à un paiement du prestataire de services.

Elle comprendra une gestion des litiges.

Elle expose une messagerie instantanée, disponible depuis un navigateur Web ou depuis lapplication mobile, pouvant garantir la preservation du secret sur toute information personnelle, du client comme du prestataire.

Ni le client ni le prestataire ne sont anonymes pour l'application, il sont même formellement authentifies, au moment de leur accord pour une première facturation en ligne, à l'occasion:

  • pour le client, à la validation d'une commande facturée (de prestation à un prestataire, ou autre).
  • pour le prestataire, de la validation de son profile professionnel, qui implique lacquittement de son adhésion forfaitaire.

La séquence logique (et simplifiable) d'une prestation canonique (sans annulation ni reclamation) est la suivante :

  1. Une commande intervient auprès d'un prestataire, elle est chiffrée et le paiement est provisionné par PayPal, non collecté.
  2. Notifié, le prestataire valide un devis, avec arrhes ou avance. il signe son devis, qui peu contenir des documents attachés à faire signer par le client, un ou des contrats, stokés au format Markdown par le prestataire dans ses contrats à faire signer.
  3. à son tour, le client est notifié et signe le devis aussi
  4. Les arrhes ou avances sont débitées sur le champ
  5. 10 jours avant la date de la prestation le reste du paiement est collecté

Dans le cas des arrhes, à tout moment, jusqu'avant la date et l'heure de la prestation, le client ou le prestataire peuvent annuler:

  • Le prestataire peut le faire, en rendant les arrhes majorées de 20%
  • Le client peut le faire, en perdant les arrhes.
  • Le prestataire peut déléguer à une équipe de son choix un filtrage des demandes des clients.

Limitations

  • à une commande, une prestation
  • Dans le cas de l'avance, une fois le paiement client autorisé, pour le moment, aucune annulation de la prestation n'est supportée.
  • Une fois passée la date de la prestation, toute reclamation nécessitera l'intervention d'un système auxiliaire (un processus humain?)
  • Un seul moyen de paiement: PayPal, depuis le Web ou l'application mobile, son interface dite dépréciée NVP/SOAP.
  • Elle ne prendra pas en charge, du moins pas encore, ni la saisie de structures de projets complexes, ni ticketing associé à la prestation.
  • Les professionnels sont tous considérés comme tierces parties, hormis le propriétaire de l'installation, dont les identifiants PayPal sont utilisés pour collecter tous les paiements. TODO Aucune edition de fiche de paye ni paiement en masse ne sont supportés pour l'instant. Seul les payments unitaires sus-cités le sont.

Paramétrage

Fichiers de configuration d'Yavsc.Org

Le paramétrage runtime d'Yavsc.Org se fait via appsettings-org.json, lu par ASP.NET Core selon la convention standard (appsettings.<ASPNETCORE_ENVIRONMENT>.json est fusionné par-dessus). Trois fichiers coexistent dans src/Yavsc.Org/, avec trois rôles distincts :

Fichier Rôle Commité ?
appsettings-org.json Modèle. Valeurs anonymisées ([Your domaine name], [YOURSMTPHOST], …). Sert de référence. Oui
appsettings-org.Development.json Surcharge locale pour ASPNETCORE_ENVIRONMENT=Development. Concrètement, Site.Authority et Site.ExternalUrl pointent sur https://localhost:5001, Site.Title/Slogan sont adaptés, et la ConnectionStrings.YavscConnection est fournie. Ignoré par .gitignore (appsettings-*.*.json) : chaque développeur crée le sien à partir de ce qui est documenté ici et du modèle appsettings-org.json. Non
appsettings-org-dist.json Généré par la cible copy-binaries du contrib/Makefile (alias make reinstall) à partir d'appsettings-org.json lors du déploiement, puis copié dans $(BASEAPPDIR). C'est un clone du modèle, juste renommé pour signaler « à éditer ». Non

Première installation sur un serveur :

make install_service        # construit, déploie, active systemd
cd $BASEAPPDIR              # voir contrib/.env
ls appsettings-org*.json    # -> appsettings-org-dist.json (le modèle, jamais éditer celui-là)
cp appsettings-org-dist.json appsettings-org.json
$EDITOR appsettings-org.json

Le Makefile renomme appsettings-org.json en appsettings-org-dist.json juste avant le cp -a vers $(BASEAPPDIR), et supprime la version appsettings-org.json du publish dir. Conséquence : un make reinstall ultérieur n'écrasera jamais ton appsettings-org.json édité — il recopiera un appsettings-org-dist.json neuf par-dessus, sans supprimer ton édition. Si tu veux repartir d'un modèle vierge, supprime d'abord appsettings-org.json du serveur ; sinon, laisse-le en place.

Valeurs minimales à renseigner pour un serveur de production :

  • Site.Authority — issuer OIDC visible de l'extérieur (URL exacte sous laquelle /.well-known/openid-configuration est servi, par exemple https://yavsc.pschneider.fr). C'est la valeur que PostIt et toutes les autres applications clientes passent dans Authority.
  • Site.ExternalUrl — URL canonique du serveur, utilisée pour générer les liens absolus dans les e-mails, construire les RedirectUris des clients OIDC tiers, etc. Depuis la migration PKCE de PostIt, le seed EF Core d'IdentityServer utilise Site.ExternalUrl pour autoriser une RedirectUri du client postit : cela permet à PostIt d'être lancé depuis une page web de Yavsc.Org (iframe launcher) sans rejet redirect_uri mismatch de l'OP. Les RedirectUris « standalone » du client (http://127.0.0.1:7890/ et android://postit-signin) restent codées en dur dans EnsureDefaultConfiguration car elles sont fixées par la plateforme, pas par l'URL de déploiement.
  • ConnectionStrings.YavscConnection — chaîne de connexion PostgreSQL (utilisateur, mot de passe, hôte, base). Privilégier dotnet user-secrets ou des variables d'environnement ASPNETCORE_* plutôt qu'un mot de passe en clair dans le fichier.
  • Smtp.* — hôte, port, identifiants SMTP pour l'envoi d'e-mails transactionnels.
  • Authentication.PayPal.* et Authentication.Google.* — clés d'API pour les fournisseurs d'identité externes utilisés dans les flows OAuth/OIDC.

Administration

Une fois le service disponible, s'enregistrer, et Visiter l'url /Administration/Take

Une nouvelle activité

On gère les activité en faisant partie du groupe des commerciaux (FrontOffice), on crée des activités en y associant des formulaires de commande et une classe de paramétrage de profiles professionnels.

Développement

Un nouvel environnement d'execution

L'impact de l'usage d'un nouveau nom denvironnement d'execution, à l'heure de cet écrit, ressemble à ceci:

  • Ajustement des listes denvironnements cités dans les pages:
    • ~/Views/Shared/_Layout.cshtml
    • ~/Views/Shared/_ValidationScriptsPartial.cshtml
    • ~/Views/Home/Index.cshtml
    • ~/Views/Home/About.cshtml

Remerciements

Photo de Dewang Guptasur Unsplash