diff --git a/internal/domain/models.go b/internal/domain/models.go
index 76cfb5a..dfa42f2 100644
--- a/internal/domain/models.go
+++ b/internal/domain/models.go
@@ -124,20 +124,11 @@ type VerifyResponse struct {
Error string `json:"error,omitempty"`
}
-// TokenDeliveryMode specifies how tokens should be delivered in redirect flows
-type TokenDeliveryMode string
-
-const (
- TokenDeliveryCookie TokenDeliveryMode = "cookie" // Token in secure cookie (default)
- TokenDeliveryQuery TokenDeliveryMode = "query" // Token in query parameter (for integrations)
-)
-
// LoginRequest represents a user login request
type LoginRequest struct {
- AppID string `json:"app_id" validate:"required"`
- Permissions []string `json:"permissions,omitempty"`
- RedirectURI string `json:"redirect_uri,omitempty"`
- TokenDelivery TokenDeliveryMode `json:"token_delivery,omitempty"` // How to deliver token in redirect flows
+ AppID string `json:"app_id" validate:"required"`
+ Permissions []string `json:"permissions,omitempty"`
+ RedirectURI string `json:"redirect_uri,omitempty"`
}
// LoginResponse represents a user login response
diff --git a/internal/handlers/auth.go b/internal/handlers/auth.go
index eb5a90e..2df152a 100644
--- a/internal/handlers/auth.go
+++ b/internal/handlers/auth.go
@@ -35,13 +35,12 @@ type AuthHandler struct {
// LoginPageData represents data passed to the login HTML template
type LoginPageData struct {
- Token string
- TokenJSON template.JS
- RedirectURLJSON template.JS
- TokenDeliveryJSON template.JS
- ExpiresAt string
- AppID string
- UserID string
+ Token string
+ TokenJSON template.JS
+ RedirectURLJSON template.JS
+ ExpiresAt string
+ AppID string
+ UserID string
}
// NewAuthHandler creates a new auth handler
@@ -92,7 +91,6 @@ func (h *AuthHandler) Login(c *gin.Context) {
// Handle HTML request (GET or POST with form data)
req.AppID = c.Query("app_id")
req.RedirectURI = c.Query("redirect_uri")
- req.TokenDelivery = domain.TokenDeliveryMode(c.DefaultQuery("token_delivery", string(domain.TokenDeliveryQuery)))
// Parse permissions from query parameter (comma-separated)
if perms := c.Query("permissions"); perms != "" {
@@ -142,56 +140,12 @@ func (h *AuthHandler) Login(c *gin.Context) {
return
}
- // Handle redirect flows
- tokenDelivery := req.TokenDelivery
- if tokenDelivery == "" {
- // Default to query delivery for redirects (external apps need token in URL)
- // Only use cookie delivery if explicitly specified
- tokenDelivery = domain.TokenDeliveryQuery
- }
-
- h.logger.Debug("Token delivery mode", zap.String("mode", string(tokenDelivery)))
-
- // Generate a secure state parameter for CSRF protection
- state := h.generateSecureState(userContext.UserID, req.AppID)
+ // Handle redirect flows - always deliver token via query parameter
var redirectURL string
-
- switch tokenDelivery {
- case domain.TokenDeliveryQuery:
- // Deliver token via query parameter (for integrations like VS Code)
- if req.RedirectURI != "" {
- redirectURL = req.RedirectURI + "?token=" + token + "&state=" + state
- }
-
- case domain.TokenDeliveryCookie:
- // Deliver token via secure cookie (default, more secure)
- c.SetSameSite(http.SameSiteStrictMode)
-
- // In development mode, make cookie accessible to JavaScript for testing
- // In production, keep HTTP-only for security
- httpOnly := !h.config.IsDevelopment()
- secure := !h.config.IsDevelopment() // Only require HTTPS in production
-
- c.SetCookie(
- "auth_token", // name
- token, // value
- 604800, // maxAge (7 days)
- "/", // path
- "", // domain (empty for current domain)
- secure, // secure (HTTPS only in production)
- httpOnly, // httpOnly (no JavaScript access in production)
- )
-
- // Redirect without token in URL for security
- if req.RedirectURI != "" {
- redirectURL = req.RedirectURI + "?state=" + state
- }
-
- default:
- // Invalid delivery mode, default to cookie
- if req.RedirectURI != "" {
- redirectURL = req.RedirectURI + "?state=" + state
- }
+ if req.RedirectURI != "" {
+ // Generate a secure state parameter for CSRF protection
+ state := h.generateSecureState(userContext.UserID, req.AppID)
+ redirectURL = req.RedirectURI + "?token=" + token + "&state=" + state
}
// Return appropriate response format
@@ -202,12 +156,12 @@ func (h *AuthHandler) Login(c *gin.Context) {
c.JSON(http.StatusOK, response)
} else {
// Render HTML page
- h.renderLoginPage(c, token, redirectURL, string(tokenDelivery), userContext.UserID, req.AppID)
+ h.renderLoginPage(c, token, redirectURL, userContext.UserID, req.AppID)
}
}
// renderLoginPage renders the HTML login page with token information
-func (h *AuthHandler) renderLoginPage(c *gin.Context, token, redirectURL, tokenDelivery, userID, appID string) {
+func (h *AuthHandler) renderLoginPage(c *gin.Context, token, redirectURL, userID, appID string) {
if h.loginTemplate == nil {
// Fallback to JSON if template not available
c.JSON(http.StatusOK, gin.H{
@@ -223,16 +177,14 @@ func (h *AuthHandler) renderLoginPage(c *gin.Context, token, redirectURL, tokenD
// Prepare template data
tokenJSON, _ := json.Marshal(token)
redirectURLJSON, _ := json.Marshal(redirectURL)
- tokenDeliveryJSON, _ := json.Marshal(tokenDelivery)
data := LoginPageData{
- Token: token,
- TokenJSON: template.JS(tokenJSON),
- RedirectURLJSON: template.JS(redirectURLJSON),
- TokenDeliveryJSON: template.JS(tokenDeliveryJSON),
- ExpiresAt: time.Now().Add(7 * 24 * time.Hour).Format("Jan 2, 2006 at 3:04 PM MST"),
- AppID: appID,
- UserID: userID,
+ Token: token,
+ TokenJSON: template.JS(tokenJSON),
+ RedirectURLJSON: template.JS(redirectURLJSON),
+ ExpiresAt: time.Now().Add(7 * 24 * time.Hour).Format("Jan 2, 2006 at 3:04 PM MST"),
+ AppID: appID,
+ UserID: userID,
}
c.Header("Content-Type", "text/html; charset=utf-8")
diff --git a/templates/login.html b/templates/login.html
index 5de35f4..b37f1de 100644
--- a/templates/login.html
+++ b/templates/login.html
@@ -157,7 +157,6 @@
// Token and redirect information from server
const token = {{.TokenJSON}};
const redirectURL = {{.RedirectURLJSON}};
- const tokenDelivery = {{.TokenDeliveryJSON}};
// Elements
const loadingDiv = document.getElementById('loading');
@@ -229,13 +228,7 @@
setTimeout(performRedirect, 1000);
});
- // Handle cookie-based token delivery
- if (tokenDelivery === 'cookie') {
- document.addEventListener('DOMContentLoaded', function() {
- const message = document.querySelector('.redirect-info');
- message.innerHTML += '
Delivery method: Secure cookie (auth_token)';
- });
- }
+ // Token is always delivered via query parameter