This commit is contained in:
ksaltnes 2026-03-31 00:09:00 +05:30 committed by GitHub
commit c6e4e87bb5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 29 additions and 13 deletions

View File

@ -6,8 +6,8 @@ import (
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
"time"
"github.com/pkg/errors"
"golang.org/x/oauth2"
@ -79,7 +79,7 @@ func (p *IdentityProvider) ExchangeToken(ctx context.Context, redirectURL, code,
// UserInfo returns the parsed user information using the given OAuth2 token.
func (p *IdentityProvider) UserInfo(token string) (*idp.IdentityProviderUserInfo, error) {
client := &http.Client{}
client := &http.Client{Timeout: 10 * time.Second}
req, err := http.NewRequest(http.MethodGet, p.config.UserInfoUrl, nil)
if err != nil {
return nil, errors.Wrap(err, "failed to create http request")
@ -101,7 +101,6 @@ func (p *IdentityProvider) UserInfo(token string) (*idp.IdentityProviderUserInfo
if err := json.Unmarshal(body, &claims); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal response body")
}
slog.Info("user info claims", "claims", claims)
userInfo := &idp.IdentityProviderUserInfo{}
if v, ok := claims[p.config.FieldMapping.Identifier].(string); ok {
userInfo.Identifier = v
@ -129,6 +128,5 @@ func (p *IdentityProvider) UserInfo(token string) (*idp.IdentityProviderUserInfo
userInfo.AvatarURL = v
}
}
slog.Info("user info", "userInfo", userInfo)
return userInfo, nil
}

View File

@ -83,8 +83,8 @@ func (s *APIV1Service) SignIn(ctx context.Context, request *v1pb.SignInRequest)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get instance general setting, error: %v", err)
}
// Check if the password auth in is allowed.
if instanceGeneralSetting.DisallowPasswordAuth && user.Role == store.RoleUser {
// Check if password auth is allowed. Enforce for all roles including admins.
if instanceGeneralSetting.DisallowPasswordAuth {
return nil, status.Errorf(codes.PermissionDenied, "password signin is not allowed")
}
existingUser = user

View File

@ -139,6 +139,9 @@ func (s *APIV1Service) CreateUser(ctx context.Context, request *v1pb.CreateUserR
}, nil
}
if len(request.User.Password) < 8 {
return nil, status.Errorf(codes.InvalidArgument, "password must be at least 8 characters")
}
passwordHash, err := bcrypt.GenerateFromPassword([]byte(request.User.Password), bcrypt.DefaultCost)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to generate password hash: %v", err)
@ -242,6 +245,9 @@ func (s *APIV1Service) UpdateUser(ctx context.Context, request *v1pb.UpdateUserR
role := convertUserRoleToStore(request.User.Role)
update.Role = &role
case "password":
if len(request.User.Password) < 8 {
return nil, status.Errorf(codes.InvalidArgument, "password must be at least 8 characters")
}
passwordHash, err := bcrypt.GenerateFromPassword([]byte(request.User.Password), bcrypt.DefaultCost)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to generate password hash: %v", err)

View File

@ -111,7 +111,17 @@ func (s *APIV1Service) RegisterGateway(ctx context.Context, echoServer *echo.Ech
}
gwGroup := echoServer.Group("")
gwGroup.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
UnsafeAllowOriginFunc: func(_ *echo.Context, origin string) (string, bool, error) {
// In demo mode, allow all origins for development convenience.
// In production, deny cross-origin requests (same-origin only).
if s.Profile.Demo {
return origin, true, nil
}
return "", false, nil
},
AllowMethods: []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete, http.MethodOptions},
AllowHeaders: []string{"Content-Type", "Authorization"},
AllowCredentials: true,
}))
// Register SSE endpoint with same CORS as rest of /api/v1.
RegisterSSERoutes(gwGroup, s.SSEHub, s.Store, s.Secret)
@ -135,7 +145,11 @@ func (s *APIV1Service) RegisterGateway(ctx context.Context, echoServer *echo.Ech
// Wrap with CORS for browser access
corsHandler := middleware.CORSWithConfig(middleware.CORSConfig{
UnsafeAllowOriginFunc: func(_ *echo.Context, origin string) (string, bool, error) {
return origin, true, nil
// In demo mode, allow all origins for development convenience.
if s.Profile.Demo {
return origin, true, nil
}
return "", false, nil
},
AllowMethods: []string{http.MethodGet, http.MethodPost, http.MethodOptions},
AllowHeaders: []string{"*"},

View File

@ -50,11 +50,9 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
return nil, errors.Wrap(err, "failed to get instance basic setting")
}
secret := "usememos"
if !profile.Demo {
secret = instanceBasicSetting.SecretKey
}
s.Secret = secret
// Always use the instance secret key, regardless of mode.
// Never fall back to a hardcoded secret, as it allows token forgery.
s.Secret = instanceBasicSetting.SecretKey
// Register healthz endpoint.
echoServer.GET("/healthz", func(c *echo.Context) error {