mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-21 14:08:15 +02:00
fix(rust) : connexion impossible sur une base dont la table sessions est ancienne
En production, l'ancien serveur gardait les sessions en mémoire : la table « sessions » de la base n'avait jamais servi et n'avait pas la forme attendue (sid, sess, expire). CREATE TABLE IF NOT EXISTS la laissait en place, et toute connexion échouait : « column "sid" does not exist ». Au démarrage, une table sessions sans ces trois colonnes est renommée (sessions_ancienne_<date>, rien n'est supprimé), son index IDX_session_expire aussi, puis la bonne table est créée. Sans effet sur une base déjà correcte. Vérifié sur une base init.sql dont la table sessions a une autre forme : connexion et session ensuite valides, ancienne table conservée, rien ne change au redémarrage suivant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ke2qyS8rgacP3ap5iezDbM
This commit is contained in:
1 file changed
+37
@@ -115,6 +115,9 @@ const SCHEMA_STATEMENTS: &[(&str, &str)] = &[
|
||||
|
||||
/// Applique les migrations de schéma, puis chiffre les secrets encore en clair
|
||||
pub async fn run_migrations(db: &PgPool, encryption_key: &str) {
|
||||
if let Err(error) = set_aside_legacy_sessions_table(db).await {
|
||||
tracing::error!(%error, "vérification de la table sessions en échec");
|
||||
}
|
||||
for (label, statement) in SCHEMA_STATEMENTS {
|
||||
if let Err(error) = sqlx::query(statement).execute(db).await {
|
||||
tracing::error!(%error, "migration « {label} » en échec");
|
||||
@@ -128,6 +131,40 @@ pub async fn run_migrations(db: &PgPool, encryption_key: &str) {
|
||||
tracing::info!("migrations de démarrage terminées");
|
||||
}
|
||||
|
||||
/// Une base peut porter une table « sessions » d'une autre forme, jamais utilisée
|
||||
/// (l'ancien serveur gardait les sessions en mémoire) : CREATE TABLE IF NOT EXISTS
|
||||
/// la laisserait en place et toute connexion échouerait (« column "sid" does not
|
||||
/// exist »). Elle est renommée, sans rien supprimer, et la bonne table est créée
|
||||
/// ensuite par SCHEMA_STATEMENTS. Les sessions ne sont que des connexions ouvertes.
|
||||
async fn set_aside_legacy_sessions_table(db: &PgPool) -> Result<(), sqlx::Error> {
|
||||
let (exists, expected_columns): (bool, i64) = sqlx::query_as(
|
||||
"SELECT to_regclass('sessions') IS NOT NULL,
|
||||
(SELECT count(*) FROM information_schema.columns
|
||||
WHERE table_schema = current_schema() AND table_name = 'sessions'
|
||||
AND column_name IN ('sid', 'sess', 'expire'))",
|
||||
)
|
||||
.fetch_one(db)
|
||||
.await?;
|
||||
if !exists || expected_columns == 3 {
|
||||
return Ok(());
|
||||
}
|
||||
let suffix = chrono::Utc::now().format("%Y%m%d%H%M%S");
|
||||
let legacy = format!("sessions_ancienne_{suffix}");
|
||||
let mut transaction = db.begin().await?;
|
||||
sqlx::query(&format!("ALTER TABLE sessions RENAME TO {legacy}"))
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
// Un index de ce nom sur l'ancienne table empêcherait de le créer sur la nouvelle
|
||||
sqlx::query(&format!(
|
||||
"ALTER INDEX IF EXISTS \"IDX_session_expire\" RENAME TO \"IDX_session_expire_ancienne_{suffix}\""
|
||||
))
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
transaction.commit().await?;
|
||||
tracing::warn!(table = %legacy, "table sessions d'une autre forme mise de côté");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Mots de passe SMTP des magasins et jetons NocoDB encore en clair → enc:v1
|
||||
async fn encrypt_plain_secrets(db: &PgPool, key: &str) -> Result<usize, sqlx::Error> {
|
||||
let mut count = 0;
|
||||
|
||||
Reference in new issue
Block a user