Compose Postgres (PostGIS + pgvector épinglé par digest), scripts de bootstrap du premier SuperAdmin, de lancement local du service et de migration des données, et le README du flux en huit étapes. Le port est lié à 127.0.0.1 et non publié : le Postgres précédent, exposé par un simple "5432:5432" avec mym/mym, a encaissé 1 074 465 échecs d'authentification entre juin et octobre 2025. Le compte mym n'a jamais été tenté — c'est le seul hasard qui a sauvé la base. Les limites de log viennent du même serveur, où un conteneur avait atteint 516 Mo sur un disque de 20 Go. Le SuperAdmin passe par le token de réinitialisation plutôt que par un INSERT : les mots de passe étant hachés en scrypt, seule l'application peut produire le bon format, et personne d'autre que l'opérateur ne connaît le mot de passe. MigrationController l'exige et la migration n'en crée aucun, MongoDB n'ayant pas de champ Role. Éprouvé sur la préprod le 07/09 : 4 instances, 315 sections migrées et 20 signalées sur 335, 2383 ressources, tout réconcilié avec MongoDB. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
51 lines
2.4 KiB
PowerShell
51 lines
2.4 KiB
PowerShell
<#
|
|
Genere le SQL qui cree le PREMIER compte SuperAdmin.
|
|
|
|
Pourquoi ce detour plutot qu'un INSERT direct avec un mot de passe :
|
|
les mots de passe sont haches en scrypt (PasswordUtils, 16384 iterations),
|
|
impossible a calculer hors .NET. Le token de reinitialisation, lui, est un
|
|
simple SHA-256 hexadecimal (PasswordTokenHelper). On laisse donc l'application
|
|
faire le hachage scrypt via set-password : le format est garanti correct, et
|
|
personne d'autre que toi ne connait le mot de passe.
|
|
|
|
MigrationController est [Authorize(Policy = SuperAdmin)] et la migration ne
|
|
cree aucun SuperAdmin (Mongo n'a pas de champ Role). Ce compte est donc le
|
|
prealable oblige a toute migration de donnees.
|
|
#>
|
|
param(
|
|
[string]$Email,
|
|
# L'instance doit EXISTER : TokensService.cs:82 fait Instances.Find(user.InstanceId)
|
|
# puis lit .PinCode sans test de nullite -> 500 au login sinon.
|
|
[string]$InstanceId = 'sa-bootstrap'
|
|
)
|
|
|
|
if ([string]::IsNullOrWhiteSpace($Email)) { $Email = Read-Host "Email du compte SuperAdmin" }
|
|
$Email = $Email.ToLower() # Authenticate fait login.email.ToLower()
|
|
|
|
$token = -join ((1..40) | ForEach-Object { '{0:x}' -f (Get-Random -Maximum 16) })
|
|
$sha = [System.Security.Cryptography.SHA256]::Create()
|
|
$hash = ($sha.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($token)) |
|
|
ForEach-Object { $_.ToString('x2') }) -join ''
|
|
|
|
Write-Host ""
|
|
Write-Host "=== ETAPE A : sur une base VIERGE uniquement, creer l'instance d'echafaudage ===" -ForegroundColor Cyan
|
|
Write-Host " (a sauter si tu passes -InstanceId d'une instance deja migree)"
|
|
Write-Host @"
|
|
insert into "Instances" ("Id","Name","DateCreation")
|
|
values ('$InstanceId','Bootstrap SuperAdmin', now());
|
|
"@
|
|
|
|
Write-Host "=== ETAPE B : creer le compte ===" -ForegroundColor Cyan
|
|
Write-Host @"
|
|
insert into "Users"
|
|
("Id","Email","Password","FirstName","LastName","Token","DateCreation","InstanceId","Role","PasswordTokenHash","PasswordTokenExpiresAt")
|
|
values
|
|
('sa-bootstrap-0001','$Email','pending','Super','Admin','',now(),'$InstanceId',0,'$hash', now() + interval '48 hours');
|
|
"@
|
|
|
|
Write-Host "=== ETAPE C : poser le mot de passe (service demarre) ===" -ForegroundColor Cyan
|
|
Write-Host " run.cmd 3-set-password.ps1 -Token $token"
|
|
Write-Host ""
|
|
Write-Host "Le token vaut 48 h et n'est ecrit dans aucun fichier : garde cette fenetre." -ForegroundColor Yellow
|
|
Write-Host "N'oublie pas de COMMITER les INSERT : DBeaver n'auto-commite pas toujours." -ForegroundColor Yellow
|