feat: apply oauth first-bind defaults and pending bind 2fa

This commit is contained in:
IanShaw027
2026-04-20 19:53:22 +08:00
parent 6ea3f42e2f
commit fb6204ea8b
8 changed files with 778 additions and 48 deletions

View File

@@ -6,6 +6,7 @@ import (
"github.com/Wei-Shaw/sub2api/internal/config"
"github.com/Wei-Shaw/sub2api/internal/handler/dto"
infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
"github.com/Wei-Shaw/sub2api/internal/pkg/ip"
"github.com/Wei-Shaw/sub2api/internal/pkg/response"
middleware2 "github.com/Wei-Shaw/sub2api/internal/server/middleware"
@@ -269,6 +270,62 @@ func (h *AuthHandler) Login2FA(c *gin.Context) {
return
}
if session.PendingOAuthBind != nil {
pendingSvc, err := h.pendingIdentityService()
if err != nil {
response.ErrorFrom(c, err)
return
}
pendingSession, err := pendingSvc.GetBrowserSession(
c.Request.Context(),
session.PendingOAuthBind.PendingSessionToken,
session.PendingOAuthBind.BrowserSessionKey,
)
if err != nil {
response.ErrorFrom(c, err)
return
}
decision, err := h.ensurePendingOAuthAdoptionDecision(c, pendingSession.ID, oauthAdoptionDecisionRequest{})
if err != nil {
response.ErrorFrom(c, err)
return
}
if err := applyPendingOAuthBinding(
c.Request.Context(),
h.entClient(),
h.authService,
pendingSession,
decision,
&user.ID,
true,
true,
); err != nil {
response.ErrorFrom(c, infraerrors.InternalServer("PENDING_AUTH_BIND_APPLY_FAILED", "failed to bind pending oauth identity").WithCause(err))
return
}
if _, err := pendingSvc.ConsumeBrowserSession(
c.Request.Context(),
pendingSession.SessionToken,
pendingSession.BrowserSessionKey,
); err != nil {
response.ErrorFrom(c, err)
return
}
secureCookie := isRequestHTTPS(c)
clearOAuthPendingSessionCookie(c, secureCookie)
clearOAuthPendingBrowserCookie(c, secureCookie)
h.authService.RecordSuccessfulLogin(c.Request.Context(), user.ID)
user, err = h.userService.GetByID(c.Request.Context(), session.UserID)
if err != nil {
response.ErrorFrom(c, err)
return
}
}
// Delete the login session (only after all checks pass)
_ = h.totpService.DeleteLoginSession(c.Request.Context(), req.TempToken)