From 86e2f15c65f19cb9d8822c06dafc1c013eab21be Mon Sep 17 00:00:00 2001 From: Abhishek Shroff Date: Wed, 9 Jul 2025 21:38:45 +0530 Subject: [PATCH] [server][auth] Add support for named api keys --- server/internal/auth/api_key.go | 11 ++++++----- server/internal/auth/password.go | 2 +- server/internal/auth/password_reset.go | 2 +- server/internal/auth/token.go | 2 +- server/internal/db/migrations/017_api_keys_name.sql | 9 +++++++++ 5 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 server/internal/db/migrations/017_api_keys_name.sql diff --git a/server/internal/auth/api_key.go b/server/internal/auth/api_key.go index 5b5cb414..86e419cc 100644 --- a/server/internal/auth/api_key.go +++ b/server/internal/auth/api_key.go @@ -26,14 +26,15 @@ func VerifyAPIKey(db db.Handler, apiKey string) (user core.User, err error) { return } -func insertAPIKey(db db.TxHandler, userID int32) (string, error) { - const q = `INSERT INTO api_keys(key, expires, user_id) VALUES (@key::TEXT, @expires::TIMESTAMPTZ, @user_id::INT)` +func insertAPIKey(db db.TxHandler, userID int32, keyName string) (string, error) { + const q = `INSERT INTO api_keys(key, expires, user_id, name) VALUES (@key::TEXT, @expires::TIMESTAMPTZ, @user_id::INT, NULLIF(@key_name, ''))` key := generateSecureKey(apiKeyLength) args := pgx.NamedArgs{ - "key": key, - "expires": time.Now().Add(apiKeyValidity), - "user_id": userID, + "key": key, + "expires": time.Now().Add(apiKeyValidity), + "user_id": userID, + "key_name": keyName, } if _, err := db.Exec(q, args); err != nil { return "", err diff --git a/server/internal/auth/password.go b/server/internal/auth/password.go index f0549b71..888d7d34 100644 --- a/server/internal/auth/password.go +++ b/server/internal/auth/password.go @@ -34,7 +34,7 @@ func VerifyUserPassword(d db.Handler, email, password string) (core.User, error) func PerformPasswordLogin(db db.TxHandler, email, password string) (core.User, string, error) { if user, err := VerifyUserPassword(db, email, password); err != nil { return core.User{}, "", err - } else if token, err := insertAPIKey(db, user.ID); err != nil { + } else if token, err := insertAPIKey(db, user.ID, ""); err != nil { return core.User{}, "", err } else { return user, token, nil diff --git a/server/internal/auth/password_reset.go b/server/internal/auth/password_reset.go index 2ad0064b..6745fd86 100644 --- a/server/internal/auth/password_reset.go +++ b/server/internal/auth/password_reset.go @@ -66,7 +66,7 @@ func ResetUserPassword(db db.TxHandler, email, resetToken, password string) (cor return core.User{}, "", ErrCredentialsInvalid } - apiToken, err := insertAPIKey(db, user.ID) + apiToken, err := insertAPIKey(db, user.ID, "") if err != nil { return core.User{}, "", err } diff --git a/server/internal/auth/token.go b/server/internal/auth/token.go index 434860c8..e9d3e142 100644 --- a/server/internal/auth/token.go +++ b/server/internal/auth/token.go @@ -23,7 +23,7 @@ func PerformTokenLogin(db db.TxHandler, token string) (core.User, string, error) return core.User{}, "", core.NewError(http.StatusBadRequest, "login_token_invalid", "The given login token is invalid") } else if user, err := core.UserByID(db, userID); err != nil { return core.User{}, "", err - } else if token, err := insertAPIKey(db, userID); err != nil { + } else if token, err := insertAPIKey(db, userID, ""); err != nil { return core.User{}, "", err } else { return user, token, err diff --git a/server/internal/db/migrations/017_api_keys_name.sql b/server/internal/db/migrations/017_api_keys_name.sql new file mode 100644 index 00000000..3ed5259a --- /dev/null +++ b/server/internal/db/migrations/017_api_keys_name.sql @@ -0,0 +1,9 @@ +ALTER TABLE api_keys ADD COLUMN name TEXT; + +CREATE UNIQUE INDEX unique_named_user_key ON api_keys(user_id, name); + +---- create above / drop below ---- + +DROP INDEX unique_named_user_key; + +ALTER TABLE api_keys DROP COLUMN name;