mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-20 17:24:16 +00:00
fix error code checking to not just check the raw string response in the case that '401' shows up in the sha256
This commit is contained in:
@@ -17,7 +17,8 @@ done
|
||||
# System packages
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update && apt-get upgrade -y
|
||||
apt-get install -y git gcc make curl libsqlite3-dev nodejs npm htop
|
||||
apt-get install -y git gcc make curl libsqlite3-dev nodejs npm htop systemd-timesyncd
|
||||
timedatectl set-ntp true
|
||||
|
||||
# Swap (for small instances)
|
||||
if [ ! -f /swapfile ]; then
|
||||
|
||||
@@ -2,27 +2,46 @@ package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"atcr.io/pkg/auth/oauth"
|
||||
"github.com/bluesky-social/indigo/atproto/atclient"
|
||||
"github.com/bluesky-social/indigo/xrpc"
|
||||
)
|
||||
|
||||
// isOAuthError checks if an error indicates OAuth authentication failure
|
||||
// These errors indicate the OAuth session is invalid and should be cleaned up
|
||||
// Uses structured error types to avoid false positives from substring matching
|
||||
func isOAuthError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check structured error types first
|
||||
var xrpcErr *xrpc.Error
|
||||
if errors.As(err, &xrpcErr) && (xrpcErr.StatusCode == 401 || xrpcErr.StatusCode == 403) {
|
||||
return true
|
||||
}
|
||||
var apiErr *atclient.APIError
|
||||
if errors.As(err, &apiErr) {
|
||||
if apiErr.StatusCode == 401 || apiErr.StatusCode == 403 {
|
||||
return true
|
||||
}
|
||||
if apiErr.Name == "InvalidToken" || apiErr.Name == "InsufficientScope" || apiErr.Name == "InvalidGrant" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: check for known auth-specific error strings that won't
|
||||
// appear in digests or URIs
|
||||
errStr := strings.ToLower(err.Error())
|
||||
return strings.Contains(errStr, "401") ||
|
||||
strings.Contains(errStr, "403") ||
|
||||
strings.Contains(errStr, "invalid_token") ||
|
||||
return strings.Contains(errStr, "invalid_token") ||
|
||||
strings.Contains(errStr, "invalid_grant") ||
|
||||
strings.Contains(errStr, "use_dpop_nonce") ||
|
||||
strings.Contains(errStr, "unauthorized") ||
|
||||
strings.Contains(errStr, "token") && strings.Contains(errStr, "expired") ||
|
||||
strings.Contains(errStr, "authentication failed")
|
||||
strings.Contains(errStr, "authentication failed") ||
|
||||
strings.Contains(errStr, "token expired")
|
||||
}
|
||||
|
||||
// handleOAuthError checks if an error is OAuth-related and invalidates UI sessions if so
|
||||
|
||||
@@ -6,6 +6,7 @@ package oauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
@@ -13,9 +14,11 @@ import (
|
||||
"time"
|
||||
|
||||
"atcr.io/pkg/atproto"
|
||||
"github.com/bluesky-social/indigo/atproto/atclient"
|
||||
"github.com/bluesky-social/indigo/atproto/atcrypto"
|
||||
"github.com/bluesky-social/indigo/atproto/auth/oauth"
|
||||
"github.com/bluesky-social/indigo/atproto/syntax"
|
||||
"github.com/bluesky-social/indigo/xrpc"
|
||||
)
|
||||
|
||||
// permissionSetExpansions maps lexicon IDs to their expanded scope format.
|
||||
@@ -312,16 +315,34 @@ func (r *Refresher) DoWithSession(ctx context.Context, did string, fn func(sessi
|
||||
}
|
||||
|
||||
// isAuthError checks if an error looks like an OAuth/auth failure
|
||||
// Uses structured error types to avoid false positives from substring matching
|
||||
// (e.g., a digest hash containing "401" in a RecordNotFound error)
|
||||
func isAuthError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check structured error types first
|
||||
var xrpcErr *xrpc.Error
|
||||
if errors.As(err, &xrpcErr) && xrpcErr.StatusCode == 401 {
|
||||
return true
|
||||
}
|
||||
var apiErr *atclient.APIError
|
||||
if errors.As(err, &apiErr) {
|
||||
if apiErr.StatusCode == 401 {
|
||||
return true
|
||||
}
|
||||
if apiErr.Name == "InvalidToken" || apiErr.Name == "InsufficientScope" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: check for known auth-specific error strings that won't
|
||||
// appear in digests or URIs
|
||||
errStr := strings.ToLower(err.Error())
|
||||
return strings.Contains(errStr, "unauthorized") ||
|
||||
strings.Contains(errStr, "invalid_token") ||
|
||||
return strings.Contains(errStr, "invalid_token") ||
|
||||
strings.Contains(errStr, "insufficient_scope") ||
|
||||
strings.Contains(errStr, "token expired") ||
|
||||
strings.Contains(errStr, "401")
|
||||
strings.Contains(errStr, "token expired")
|
||||
}
|
||||
|
||||
// resumeSession loads a session from storage
|
||||
|
||||
Reference in New Issue
Block a user