- Add auth HTTP handlers (login, me, logout) with proper JSON responses - Enforce HS256 via jwt.WithValidMethods to prevent algorithm confusion attacks - Add context helpers for extracting operator ID and role from JWT claims - Add comprehensive auth test suite (11 unit tests + 6 integration tests) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
101 lines
8.9 KiB
Go
101 lines
8.9 KiB
Go
package blind
|
|
|
|
// BuiltinStructures returns the built-in blind structures that ship with the app.
|
|
// These are used by the seed migration to populate the database on first boot.
|
|
|
|
// TurboLevels returns the Turbo blind structure (~2hr for 20 players, 15-min levels).
|
|
func TurboLevels() []BlindLevel {
|
|
return []BlindLevel{
|
|
{Position: 0, LevelType: "round", GameType: "nlhe", SmallBlind: 25, BigBlind: 50, DurationSeconds: 900},
|
|
{Position: 1, LevelType: "round", GameType: "nlhe", SmallBlind: 50, BigBlind: 100, DurationSeconds: 900},
|
|
{Position: 2, LevelType: "round", GameType: "nlhe", SmallBlind: 75, BigBlind: 150, DurationSeconds: 900},
|
|
{Position: 3, LevelType: "round", GameType: "nlhe", SmallBlind: 100, BigBlind: 200, DurationSeconds: 900},
|
|
{Position: 4, LevelType: "break", GameType: "nlhe", DurationSeconds: 600},
|
|
{Position: 5, LevelType: "round", GameType: "nlhe", SmallBlind: 150, BigBlind: 300, Ante: 300, DurationSeconds: 900},
|
|
{Position: 6, LevelType: "round", GameType: "nlhe", SmallBlind: 200, BigBlind: 400, Ante: 400, DurationSeconds: 900},
|
|
{Position: 7, LevelType: "round", GameType: "nlhe", SmallBlind: 300, BigBlind: 600, Ante: 600, DurationSeconds: 900},
|
|
{Position: 8, LevelType: "round", GameType: "nlhe", SmallBlind: 400, BigBlind: 800, Ante: 800, DurationSeconds: 900},
|
|
{Position: 9, LevelType: "break", GameType: "nlhe", DurationSeconds: 600},
|
|
{Position: 10, LevelType: "round", GameType: "nlhe", SmallBlind: 600, BigBlind: 1200, Ante: 1200, DurationSeconds: 900},
|
|
{Position: 11, LevelType: "round", GameType: "nlhe", SmallBlind: 800, BigBlind: 1600, Ante: 1600, DurationSeconds: 900},
|
|
{Position: 12, LevelType: "round", GameType: "nlhe", SmallBlind: 1000, BigBlind: 2000, Ante: 2000, DurationSeconds: 900},
|
|
{Position: 13, LevelType: "round", GameType: "nlhe", SmallBlind: 1500, BigBlind: 3000, Ante: 3000, DurationSeconds: 900},
|
|
{Position: 14, LevelType: "round", GameType: "nlhe", SmallBlind: 2000, BigBlind: 4000, Ante: 4000, DurationSeconds: 900},
|
|
}
|
|
}
|
|
|
|
// StandardLevels returns the Standard blind structure (~3-4hr for 20 players, 20-min levels).
|
|
func StandardLevels() []BlindLevel {
|
|
return []BlindLevel{
|
|
{Position: 0, LevelType: "round", GameType: "nlhe", SmallBlind: 25, BigBlind: 50, DurationSeconds: 1200},
|
|
{Position: 1, LevelType: "round", GameType: "nlhe", SmallBlind: 50, BigBlind: 100, DurationSeconds: 1200},
|
|
{Position: 2, LevelType: "round", GameType: "nlhe", SmallBlind: 75, BigBlind: 150, DurationSeconds: 1200},
|
|
{Position: 3, LevelType: "round", GameType: "nlhe", SmallBlind: 100, BigBlind: 200, DurationSeconds: 1200},
|
|
{Position: 4, LevelType: "round", GameType: "nlhe", SmallBlind: 150, BigBlind: 300, DurationSeconds: 1200},
|
|
{Position: 5, LevelType: "break", GameType: "nlhe", DurationSeconds: 600},
|
|
{Position: 6, LevelType: "round", GameType: "nlhe", SmallBlind: 200, BigBlind: 400, Ante: 400, DurationSeconds: 1200},
|
|
{Position: 7, LevelType: "round", GameType: "nlhe", SmallBlind: 300, BigBlind: 600, Ante: 600, DurationSeconds: 1200},
|
|
{Position: 8, LevelType: "round", GameType: "nlhe", SmallBlind: 400, BigBlind: 800, Ante: 800, DurationSeconds: 1200},
|
|
{Position: 9, LevelType: "round", GameType: "nlhe", SmallBlind: 500, BigBlind: 1000, Ante: 1000, DurationSeconds: 1200},
|
|
{Position: 10, LevelType: "break", GameType: "nlhe", DurationSeconds: 600},
|
|
{Position: 11, LevelType: "round", GameType: "nlhe", SmallBlind: 600, BigBlind: 1200, Ante: 1200, DurationSeconds: 1200},
|
|
{Position: 12, LevelType: "round", GameType: "nlhe", SmallBlind: 800, BigBlind: 1600, Ante: 1600, DurationSeconds: 1200},
|
|
{Position: 13, LevelType: "round", GameType: "nlhe", SmallBlind: 1000, BigBlind: 2000, Ante: 2000, DurationSeconds: 1200},
|
|
{Position: 14, LevelType: "round", GameType: "nlhe", SmallBlind: 1500, BigBlind: 3000, Ante: 3000, DurationSeconds: 1200},
|
|
{Position: 15, LevelType: "round", GameType: "nlhe", SmallBlind: 2000, BigBlind: 4000, Ante: 4000, DurationSeconds: 1200},
|
|
{Position: 16, LevelType: "round", GameType: "nlhe", SmallBlind: 3000, BigBlind: 6000, Ante: 6000, DurationSeconds: 1200},
|
|
}
|
|
}
|
|
|
|
// DeepStackLevels returns the Deep Stack blind structure (~5-6hr for 20 players, 30-min levels).
|
|
func DeepStackLevels() []BlindLevel {
|
|
return []BlindLevel{
|
|
{Position: 0, LevelType: "round", GameType: "nlhe", SmallBlind: 25, BigBlind: 50, DurationSeconds: 1800},
|
|
{Position: 1, LevelType: "round", GameType: "nlhe", SmallBlind: 50, BigBlind: 100, DurationSeconds: 1800},
|
|
{Position: 2, LevelType: "round", GameType: "nlhe", SmallBlind: 75, BigBlind: 150, DurationSeconds: 1800},
|
|
{Position: 3, LevelType: "round", GameType: "nlhe", SmallBlind: 100, BigBlind: 200, DurationSeconds: 1800},
|
|
{Position: 4, LevelType: "round", GameType: "nlhe", SmallBlind: 150, BigBlind: 300, DurationSeconds: 1800},
|
|
{Position: 5, LevelType: "break", GameType: "nlhe", DurationSeconds: 900},
|
|
{Position: 6, LevelType: "round", GameType: "nlhe", SmallBlind: 200, BigBlind: 400, DurationSeconds: 1800},
|
|
{Position: 7, LevelType: "round", GameType: "nlhe", SmallBlind: 250, BigBlind: 500, Ante: 500, DurationSeconds: 1800},
|
|
{Position: 8, LevelType: "round", GameType: "nlhe", SmallBlind: 300, BigBlind: 600, Ante: 600, DurationSeconds: 1800},
|
|
{Position: 9, LevelType: "round", GameType: "nlhe", SmallBlind: 400, BigBlind: 800, Ante: 800, DurationSeconds: 1800},
|
|
{Position: 10, LevelType: "break", GameType: "nlhe", DurationSeconds: 900},
|
|
{Position: 11, LevelType: "round", GameType: "nlhe", SmallBlind: 500, BigBlind: 1000, Ante: 1000, DurationSeconds: 1800},
|
|
{Position: 12, LevelType: "round", GameType: "nlhe", SmallBlind: 600, BigBlind: 1200, Ante: 1200, DurationSeconds: 1800},
|
|
{Position: 13, LevelType: "round", GameType: "nlhe", SmallBlind: 800, BigBlind: 1600, Ante: 1600, DurationSeconds: 1800},
|
|
{Position: 14, LevelType: "round", GameType: "nlhe", SmallBlind: 1000, BigBlind: 2000, Ante: 2000, DurationSeconds: 1800},
|
|
{Position: 15, LevelType: "break", GameType: "nlhe", DurationSeconds: 900},
|
|
{Position: 16, LevelType: "round", GameType: "nlhe", SmallBlind: 1500, BigBlind: 3000, Ante: 3000, DurationSeconds: 1800},
|
|
{Position: 17, LevelType: "round", GameType: "nlhe", SmallBlind: 2000, BigBlind: 4000, Ante: 4000, DurationSeconds: 1800},
|
|
{Position: 18, LevelType: "round", GameType: "nlhe", SmallBlind: 3000, BigBlind: 6000, Ante: 6000, DurationSeconds: 1800},
|
|
{Position: 19, LevelType: "round", GameType: "nlhe", SmallBlind: 4000, BigBlind: 8000, Ante: 8000, DurationSeconds: 1800},
|
|
{Position: 20, LevelType: "round", GameType: "nlhe", SmallBlind: 5000, BigBlind: 10000, Ante: 10000, DurationSeconds: 1800},
|
|
}
|
|
}
|
|
|
|
// WSOPStyleLevels returns the WSOP-style blind structure (60-min levels, with antes from level 4, BB ante option).
|
|
func WSOPStyleLevels() []BlindLevel {
|
|
return []BlindLevel{
|
|
{Position: 0, LevelType: "round", GameType: "nlhe", SmallBlind: 25, BigBlind: 50, DurationSeconds: 3600},
|
|
{Position: 1, LevelType: "round", GameType: "nlhe", SmallBlind: 50, BigBlind: 100, DurationSeconds: 3600},
|
|
{Position: 2, LevelType: "round", GameType: "nlhe", SmallBlind: 75, BigBlind: 150, DurationSeconds: 3600},
|
|
{Position: 3, LevelType: "round", GameType: "nlhe", SmallBlind: 100, BigBlind: 200, BBAnte: 200, DurationSeconds: 3600},
|
|
{Position: 4, LevelType: "break", GameType: "nlhe", DurationSeconds: 1200},
|
|
{Position: 5, LevelType: "round", GameType: "nlhe", SmallBlind: 150, BigBlind: 300, BBAnte: 300, DurationSeconds: 3600},
|
|
{Position: 6, LevelType: "round", GameType: "nlhe", SmallBlind: 200, BigBlind: 400, BBAnte: 400, DurationSeconds: 3600},
|
|
{Position: 7, LevelType: "round", GameType: "nlhe", SmallBlind: 250, BigBlind: 500, BBAnte: 500, DurationSeconds: 3600},
|
|
{Position: 8, LevelType: "round", GameType: "nlhe", SmallBlind: 300, BigBlind: 600, BBAnte: 600, DurationSeconds: 3600},
|
|
{Position: 9, LevelType: "break", GameType: "nlhe", DurationSeconds: 1200},
|
|
{Position: 10, LevelType: "round", GameType: "nlhe", SmallBlind: 400, BigBlind: 800, BBAnte: 800, DurationSeconds: 3600},
|
|
{Position: 11, LevelType: "round", GameType: "nlhe", SmallBlind: 500, BigBlind: 1000, BBAnte: 1000, DurationSeconds: 3600},
|
|
{Position: 12, LevelType: "round", GameType: "nlhe", SmallBlind: 600, BigBlind: 1200, BBAnte: 1200, DurationSeconds: 3600},
|
|
{Position: 13, LevelType: "round", GameType: "nlhe", SmallBlind: 800, BigBlind: 1600, BBAnte: 1600, DurationSeconds: 3600},
|
|
{Position: 14, LevelType: "break", GameType: "nlhe", DurationSeconds: 1200},
|
|
{Position: 15, LevelType: "round", GameType: "nlhe", SmallBlind: 1000, BigBlind: 2000, BBAnte: 2000, DurationSeconds: 3600},
|
|
{Position: 16, LevelType: "round", GameType: "nlhe", SmallBlind: 1500, BigBlind: 3000, BBAnte: 3000, DurationSeconds: 3600},
|
|
{Position: 17, LevelType: "round", GameType: "nlhe", SmallBlind: 2000, BigBlind: 4000, BBAnte: 4000, DurationSeconds: 3600},
|
|
{Position: 18, LevelType: "round", GameType: "nlhe", SmallBlind: 2500, BigBlind: 5000, BBAnte: 5000, DurationSeconds: 3600},
|
|
{Position: 19, LevelType: "round", GameType: "nlhe", SmallBlind: 3000, BigBlind: 6000, BBAnte: 6000, DurationSeconds: 3600},
|
|
}
|
|
}
|