halkyon/apps/todo/halkyon_todo_server/migrations/20261021110200318-second-factor-paths/migration.json
Tizian 「ティツィアーン」 4d1cd2045c
fix(auth): codes after the recovery phrase count apart from the password's
The full reading's M3: whoever knows the password made the account's codes
wait, and that wait refused the phrase's owner their reset too, so they were
held out of both without end. Codes now count per account and per way they
came (SecondFactorPath: after the password, after the phrase), each with
its own waits; a code accepted either way clears both.

Migration (module, Learn's and Todo's servers; Learn's device schema
rebuilds the server-only table):
  DROP INDEX "second_factor_failures_person_idx";
  ALTER TABLE "second_factor_failures" ADD COLUMN "path" text NOT NULL
    DEFAULT 'password'::text;
  CREATE UNIQUE INDEX "second_factor_failures_person_idx" ON
    "second_factor_failures" USING btree ("authUserId", "path");
Existing rows are the password's, unique per account, so unique per
account and way too.

Also the hosts' generated future calls, for the pruning's doc comment the
lapsed resets' commit changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-23 14:12:52 +02:00

80 lines
No EOL
2.5 KiB
JSON

{
"__className__": "serverpod.DatabaseMigration",
"actions": [
{
"__className__": "serverpod.DatabaseMigrationAction",
"type": "alterTable",
"alterTable": {
"__className__": "serverpod.TableMigration",
"name": "second_factor_failures",
"schema": "public",
"addColumns": [
{
"__className__": "serverpod.ColumnDefinition",
"name": "path",
"fieldName": "path",
"columnType": 0,
"isNullable": false,
"columnDefault": "'password'",
"dartType": "protocol:SecondFactorPath"
}
],
"deleteColumns": [],
"modifyColumns": [],
"addIndexes": [
{
"__className__": "serverpod.IndexDefinition",
"indexName": "second_factor_failures_person_idx",
"elements": [
{
"__className__": "serverpod.IndexElementDefinition",
"type": 0,
"definition": "authUserId"
},
{
"__className__": "serverpod.IndexElementDefinition",
"type": 0,
"definition": "path"
}
],
"type": "btree",
"isUnique": true,
"isPrimary": false
}
],
"deleteIndexes": [
"second_factor_failures_person_idx"
],
"addForeignKeys": [],
"deleteForeignKeys": [],
"warnings": [
{
"__className__": "serverpod.DatabaseMigrationWarning",
"type": "uniqueIndexCreated",
"message": "Unique index \"second_factor_failures_person_idx\" is added to table \"second_factor_failures\". If there are existing rows with duplicate values, this migration will fail.",
"table": "second_factor_failures",
"columns": [
"authUserId",
"path"
],
"destrucive": false
}
]
}
}
],
"warnings": [
{
"__className__": "serverpod.DatabaseMigrationWarning",
"type": "uniqueIndexCreated",
"message": "Unique index \"second_factor_failures_person_idx\" is added to table \"second_factor_failures\". If there are existing rows with duplicate values, this migration will fail.",
"table": "second_factor_failures",
"columns": [
"authUserId",
"path"
],
"destrucive": false
}
],
"migrationApiVersion": 1
}