package storage import ( "MiauInv/models" "database/sql" "errors" "log" _ "github.com/glebarez/go-sqlite" ) var ErrNotFound = sql.ErrNoRows var DB *sql.DB func InitDB(filepath string) error { var err error DB, err = sql.Open("sqlite", filepath) if err != nil { return err } schema := ` PRAGMA foreign_keys = ON; CREATE TABLE IF NOT EXISTS users ( id TEXT PRIMARY KEY, username TEXT NOT NULL UNIQUE, password TEXT NOT NULL, role TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS refresh_tokens ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, token_hash TEXT NOT NULL, expires_at INTEGER NOT NULL, created_at INTEGER NOT NULL, revoked INTEGER NOT NULL DEFAULT 0, device_info TEXT, FOREIGN KEY(user_id) REFERENCES users(id) ); CREATE TABLE IF NOT EXISTS items ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, category TEXT, total_quantity INTEGER NOT NULL DEFAULT 0 ); CREATE TABLE IF NOT EXISTS locations ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS projects ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS item_allocations ( id INTEGER PRIMARY KEY AUTOINCREMENT, item_id INTEGER NOT NULL, location_id INTEGER, project_id INTEGER, quantity INTEGER NOT NULL ); ` _, err = DB.Exec(schema) if err != nil { log.Fatal(err) } return err } // Refresh Tokens func AddRefreshToken(token *models.RefreshToken) error { _, err := DB.Exec("INSERT INTO refresh_tokens(id, user_id, token_hash, expires_at, created_at, revoked, device_info) VALUES (?, ?, ?, ?, ?, ?, ?)", token.ID, token.UserID, token.Token, token.ExpiresAt, token.CreatedAt, token.Revoked, token.DeviceInfo) return err } func GetRefreshToken(token string) (models.RefreshToken, error) { row := DB.QueryRow("SELECT * FROM refresh_tokens WHERE token_hash = ?", token) var refresh_token models.RefreshToken err := row.Scan(&refresh_token.ID, &refresh_token.UserID, &refresh_token.Token, &refresh_token.ExpiresAt, &refresh_token.CreatedAt, &refresh_token.Revoked, &refresh_token.DeviceInfo) return refresh_token, err } func RevokeRefreshToken(tokenID string) error { if DB == nil { return errors.New("db not initialized") } res, err := DB.Exec(` UPDATE refresh_tokens SET revoked = 1 WHERE id = ? `, tokenID) if err != nil { return err } n, err := res.RowsAffected() if err != nil { return err } if n == 0 { return ErrNotFound } return nil } func RevokeAllRefreshTokensForUser(userID string) error { if DB == nil { return errors.New("db not initialized") } _, err := DB.Exec(` UPDATE refresh_tokens SET revoked = 1 WHERE user_id = ? `, userID) return err }