Add refresh token authentication system
Implement complete refresh token flow for improved security: - Short-lived access tokens (configurable, default 1h) - Long-lived refresh tokens (configurable, default 7d) - Automatic token rotation on refresh - Token revocation for proper logout Domain layer: - Add RefreshToken entity with validation and revocation - Add RefreshTokenRepository interface Application layer: - Add RefreshTokenHandler for token refresh operations - Add RevokeTokenHandler for single token revocation - Add RevokeAllTokensHandler for user-wide revocation Infrastructure layer: - Implement SQLite RefreshTokenRepository - Add refresh_tokens table migration with indexes - Add parseDuration helper for flexible time configuration HTTP layer: - Add POST /api/v1/auth/refresh endpoint - Add POST /api/v1/auth/logout endpoint - Update login/register to return refresh tokens - Improve Swagger documentation with clear descriptions Configuration: - Update .env.example with secure token expiry defaults - Add support for minute/hour/day duration formats Tests: - Fix test suite to work with new signatures - All existing tests passing
This commit is contained in:
@@ -9,6 +9,7 @@ func RunMigrations(db *sql.DB) error {
|
||||
createUsersTable,
|
||||
createHabitsTable,
|
||||
createHabitEntriesTable,
|
||||
createRefreshTokensTable,
|
||||
createIndexes,
|
||||
}
|
||||
|
||||
@@ -62,9 +63,23 @@ CREATE TABLE IF NOT EXISTS habit_entries (
|
||||
);
|
||||
`
|
||||
|
||||
const createRefreshTokensTable = `
|
||||
CREATE TABLE IF NOT EXISTS refresh_tokens (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL,
|
||||
token TEXT UNIQUE NOT NULL,
|
||||
expires_at DATETIME NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
revoked_at DATETIME,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
`
|
||||
|
||||
const createIndexes = `
|
||||
CREATE INDEX IF NOT EXISTS idx_habits_user ON habits(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_habits_active ON habits(user_id, archived_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_entries_habit ON habit_entries(habit_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_entries_scheduled ON habit_entries(scheduled_date);
|
||||
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user ON refresh_tokens(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_token ON refresh_tokens(token);
|
||||
`
|
||||
|
||||
Reference in New Issue
Block a user