diff --git a/backend/internal/common/errors.go b/backend/internal/common/errors.go index 873054de..14536541 100644 --- a/backend/internal/common/errors.go +++ b/backend/internal/common/errors.go @@ -88,11 +88,6 @@ type NotSignedInError struct{} func (e NotSignedInError) Error() string { return "You are not signed in" } func (e NotSignedInError) HttpStatusCode() int { return http.StatusUnauthorized } -type MissingAccessToken struct{} - -func (e MissingAccessToken) Error() string { return "Missing access token" } -func (e MissingAccessToken) HttpStatusCode() int { return http.StatusUnauthorized } - type MissingPermissionError struct{} func (e MissingPermissionError) Error() string { @@ -115,11 +110,6 @@ type UserNotFoundError struct{} func (e UserNotFoundError) Error() string { return "User not found" } func (e UserNotFoundError) HttpStatusCode() int { return http.StatusNotFound } -type ClientIdOrSecretNotProvidedError struct{} - -func (e ClientIdOrSecretNotProvidedError) Error() string { return "Client id or secret not provided" } -func (e ClientIdOrSecretNotProvidedError) HttpStatusCode() int { return http.StatusBadRequest } - type WrongFileTypeError struct { ExpectedFileType string } diff --git a/backend/internal/dto/dto_normalize.go b/backend/internal/dto/dto_normalize.go index b73910c4..b988e84e 100644 --- a/backend/internal/dto/dto_normalize.go +++ b/backend/internal/dto/dto_normalize.go @@ -1,7 +1,6 @@ package dto import ( - "net/http" "reflect" "github.com/gin-gonic/gin" @@ -73,22 +72,3 @@ loop: func ShouldBindWithNormalizedJSON(ctx *gin.Context, obj any) error { return ctx.ShouldBindWith(obj, binding.JSON) } - -type NormalizerJSONBinding struct{} - -func (NormalizerJSONBinding) Name() string { - return "json" -} - -func (NormalizerJSONBinding) Bind(req *http.Request, obj any) error { - // Use the default JSON binder - err := binding.JSON.Bind(req, obj) - if err != nil { - return err - } - - // Perform normalization - Normalize(obj) - - return nil -} diff --git a/backend/internal/oidc/authorization_service_test.go b/backend/internal/oidc/authorization_service_test.go index 15659015..6add3972 100644 --- a/backend/internal/oidc/authorization_service_test.go +++ b/backend/internal/oidc/authorization_service_test.go @@ -304,13 +304,12 @@ func TestAuthorizationServiceAuthorizeSwitchesUserAndResetsRequirements(t *testi ClientID: clientID, Scope: datatype.StringList{"openid"}, }).Error) - reauthenticatedAt := datatype.DateTime(time.Now().Add(-time.Minute).UTC()) require.NoError(t, db.Create(&InteractionSession{ Base: model.Base{ID: interactionID}, Scopes: datatype.StringList{"openid"}, ClientID: clientID, UserID: stringPointer(userID), - ReauthenticatedAt: &reauthenticatedAt, + ReauthenticatedAt: new(datatype.DateTime(time.Now().Add(-time.Minute).UTC())), ReauthenticationRequired: false, RequestedAt: datatype.DateTime(time.Now().UTC()), Parameters: map[string]string{ @@ -766,13 +765,12 @@ func TestAuthorizationServiceAuthorizeUsesCompletedReauthenticationTime(t *testi ClientID: clientID, Scope: datatype.StringList{"openid"}, }).Error) - reauthenticatedAtValue := datatype.DateTime(reauthenticatedAt) require.NoError(t, db.Create(&InteractionSession{ Base: model.Base{ID: interactionID}, Scopes: datatype.StringList{"openid"}, ClientID: clientID, ReauthenticationRequired: false, - ReauthenticatedAt: &reauthenticatedAtValue, + ReauthenticatedAt: new(datatype.DateTime(reauthenticatedAt)), Parameters: map[string]string{ "max_age": "1", }, @@ -815,14 +813,13 @@ func TestAuthorizationServiceAuthorizeUsesOriginalInteractionRequestTime(t *test ClientID: clientID, Scope: datatype.StringList{"openid"}, }).Error) - reauthenticatedAtValue := datatype.DateTime(reauthenticatedAt) require.NoError(t, db.Create(&InteractionSession{ Base: model.Base{ID: interactionID}, Scopes: datatype.StringList{"openid"}, ClientID: clientID, ReauthenticationRequired: false, RequestedAt: datatype.DateTime(originalRequestedAt), - ReauthenticatedAt: &reauthenticatedAtValue, + ReauthenticatedAt: new(datatype.DateTime(reauthenticatedAt)), Parameters: map[string]string{ "prompt": "login", }, diff --git a/backend/internal/oidc/cleanup_test.go b/backend/internal/oidc/cleanup_test.go index 1e367907..df1ff251 100644 --- a/backend/internal/oidc/cleanup_test.go +++ b/backend/internal/oidc/cleanup_test.go @@ -18,11 +18,10 @@ import ( func TestCleanupExpiredOAuth2SessionsKeepsInvalidatedButUnexpiredSessions(t *testing.T) { db := testutils.NewDatabaseForTest(t) - past := datatype.DateTime(time.Now().Add(-time.Hour)) future := datatype.DateTime(time.Now().Add(time.Hour)) rows := []OAuth2Session{ - {Base: model.Base{ID: "expired"}, Kind: "access_token", Key: "k-expired", RequestID: "r1", Active: true, RequestData: "{}", ExpiresAt: &past}, + {Base: model.Base{ID: "expired"}, Kind: "access_token", Key: "k-expired", RequestID: "r1", Active: true, RequestData: "{}", ExpiresAt: new(datatype.DateTime(time.Now().Add(-time.Hour)))}, {Base: model.Base{ID: "rotated"}, Kind: "refresh_token", Key: "k-rotated", RequestID: "r2", Active: false, RequestData: "{}", ExpiresAt: &future}, {Base: model.Base{ID: "active"}, Kind: "refresh_token", Key: "k-active", RequestID: "r3", Active: true, RequestData: "{}", ExpiresAt: &future}, } diff --git a/backend/internal/service/jwt_service.go b/backend/internal/service/jwt_service.go index 5eafd310..41ac6937 100644 --- a/backend/internal/service/jwt_service.go +++ b/backend/internal/service/jwt_service.go @@ -290,19 +290,6 @@ func (s *JwtService) GetKeyID() (string, bool) { return s.privateKey.KeyID() } -// GetIsAdmin returns the value of the "isAdmin" claim in the token -func GetIsAdmin(token jwt.Token) (bool, error) { - if !token.Has(IsAdminClaim) { - return false, nil - } - var isAdmin bool - err := token.Get(IsAdminClaim, &isAdmin) - if err != nil { - return false, fmt.Errorf("failed to get 'isAdmin' claim from token: %w", err) - } - return isAdmin, nil -} - // GetAuthenticationMethod returns the first authentication method in the "amr" claim in the token func GetAuthenticationMethod(token jwt.Token) (string, error) { if !token.Has(common.AuthenticationMethodsClaim) { diff --git a/backend/internal/service/jwt_service_test.go b/backend/internal/service/jwt_service_test.go index 75408bfc..8d3f94aa 100644 --- a/backend/internal/service/jwt_service_test.go +++ b/backend/internal/service/jwt_service_test.go @@ -319,9 +319,11 @@ func TestGenerateVerifyAccessToken(t *testing.T) { subject, ok := claims.Subject() _ = assert.True(t, ok, "User ID not found in token") && assert.Equal(t, user.ID, subject, "Token subject should match user ID") - isAdmin, err := GetIsAdmin(claims) - _ = assert.NoError(t, err, "Failed to get isAdmin claim") && - assert.False(t, isAdmin, "isAdmin should be false") + isAdmin := false + if claims.Has(IsAdminClaim) { + require.NoError(t, claims.Get(IsAdminClaim, &isAdmin), "Failed to get isAdmin claim") + } + assert.False(t, isAdmin, "isAdmin should be false") authenticationMethod, err := GetAuthenticationMethod(claims) _ = assert.NoError(t, err, "Failed to get amr claim") && assert.Empty(t, authenticationMethod, "amr should be empty when not specified") @@ -354,9 +356,11 @@ func TestGenerateVerifyAccessToken(t *testing.T) { claims, err := service.VerifyAccessToken(tokenString) require.NoError(t, err, "Failed to verify generated token") - isAdmin, err := GetIsAdmin(claims) - _ = assert.NoError(t, err, "Failed to get isAdmin claim") && - assert.True(t, isAdmin, "isAdmin should be true") + isAdmin := false + if claims.Has(IsAdminClaim) { + require.NoError(t, claims.Get(IsAdminClaim, &isAdmin), "Failed to get isAdmin claim") + } + assert.True(t, isAdmin, "isAdmin should be true") subject, ok := claims.Subject() _ = assert.True(t, ok, "User ID not found in token") && assert.Equal(t, adminUser.ID, subject, "Token subject should match user ID") @@ -428,9 +432,11 @@ func TestGenerateVerifyAccessToken(t *testing.T) { subject, ok := claims.Subject() _ = assert.True(t, ok, "User ID not found in token") && assert.Equal(t, user.ID, subject, "Token subject should match user ID") - isAdmin, err := GetIsAdmin(claims) - _ = assert.NoError(t, err, "Failed to get isAdmin claim") && - assert.True(t, isAdmin, "isAdmin should be true") + isAdmin := false + if claims.Has(IsAdminClaim) { + require.NoError(t, claims.Get(IsAdminClaim, &isAdmin), "Failed to get isAdmin claim") + } + assert.True(t, isAdmin, "isAdmin should be true") publicKey, err := service.GetPublicJWK() require.NoError(t, err) @@ -465,9 +471,11 @@ func TestGenerateVerifyAccessToken(t *testing.T) { subject, ok := claims.Subject() _ = assert.True(t, ok, "User ID not found in token") && assert.Equal(t, user.ID, subject, "Token subject should match user ID") - isAdmin, err := GetIsAdmin(claims) - _ = assert.NoError(t, err, "Failed to get isAdmin claim") && - assert.True(t, isAdmin, "isAdmin should be true") + isAdmin := false + if claims.Has(IsAdminClaim) { + require.NoError(t, claims.Get(IsAdminClaim, &isAdmin), "Failed to get isAdmin claim") + } + assert.True(t, isAdmin, "isAdmin should be true") publicKey, err := service.GetPublicJWK() require.NoError(t, err) @@ -502,9 +510,11 @@ func TestGenerateVerifyAccessToken(t *testing.T) { subject, ok := claims.Subject() _ = assert.True(t, ok, "User ID not found in token") && assert.Equal(t, user.ID, subject, "Token subject should match user ID") - isAdmin, err := GetIsAdmin(claims) - _ = assert.NoError(t, err, "Failed to get isAdmin claim") && - assert.True(t, isAdmin, "isAdmin should be true") + isAdmin := false + if claims.Has(IsAdminClaim) { + require.NoError(t, claims.Get(IsAdminClaim, &isAdmin), "Failed to get isAdmin claim") + } + assert.True(t, isAdmin, "isAdmin should be true") publicKey, err := service.GetPublicJWK() require.NoError(t, err) diff --git a/backend/internal/utils/file_util.go b/backend/internal/utils/file_util.go index 15863068..6a31d993 100644 --- a/backend/internal/utils/file_util.go +++ b/backend/internal/utils/file_util.go @@ -81,18 +81,6 @@ func GetImageExtensionFromMimeType(mimeType string) string { } } -// FileExists returns true if a file exists on disk and is a regular file -func FileExists(path string) (bool, error) { - s, err := os.Stat(path) - if err != nil { - if os.IsNotExist(err) { - err = nil - } - return false, err - } - return !s.IsDir(), nil -} - // IsWritableDir checks if a directory exists and is writable func IsWritableDir(dir string) (bool, error) { // Check if directory exists and it's actually a directory diff --git a/backend/internal/utils/hash_util.go b/backend/internal/utils/hash_util.go index 0fc37d27..d80c41f1 100644 --- a/backend/internal/utils/hash_util.go +++ b/backend/internal/utils/hash_util.go @@ -3,28 +3,9 @@ package utils import ( "crypto/sha256" "encoding/hex" - "fmt" - "io" - "os" ) func CreateSha256Hash(input string) string { hash := sha256.Sum256([]byte(input)) return hex.EncodeToString(hash[:]) } - -func CreateSha256FileHash(filePath string) ([]byte, error) { - f, err := os.Open(filePath) - if err != nil { - return nil, fmt.Errorf("failed to open file: %w", err) - } - defer f.Close() - - h := sha256.New() - _, err = io.Copy(h, f) - if err != nil { - return nil, fmt.Errorf("failed to read file: %w", err) - } - - return h.Sum(nil), nil -} diff --git a/backend/internal/utils/http_util.go b/backend/internal/utils/http_util.go index bd9cc028..06811c4b 100644 --- a/backend/internal/utils/http_util.go +++ b/backend/internal/utils/http_util.go @@ -1,48 +1,12 @@ package utils import ( - "net/http" - "net/url" "strconv" - "strings" "time" "github.com/gin-gonic/gin" ) -// BearerAuth returns the value of the bearer token in the Authorization header if present -func BearerAuth(r *http.Request) (string, bool) { - const prefix = "bearer " - - authHeader := r.Header.Get("Authorization") - if len(authHeader) >= len(prefix) && strings.ToLower(authHeader[:len(prefix)]) == prefix { - return authHeader[len(prefix):], true - } - - return "", false -} - -// OAuthClientBasicAuth returns the OAuth client ID and secret provided in the request's -// Authorization header, if present. See RFC 6749, Section 2.3. -func OAuthClientBasicAuth(r *http.Request) (clientID, clientSecret string, ok bool) { - clientID, clientSecret, ok = r.BasicAuth() - if !ok { - return "", "", false - } - - clientID, err := url.QueryUnescape(clientID) - if err != nil { - return "", "", false - } - - clientSecret, err = url.QueryUnescape(clientSecret) - if err != nil { - return "", "", false - } - - return clientID, clientSecret, true -} - // SetCacheControlHeader sets the Cache-Control header for the response. func SetCacheControlHeader(ctx *gin.Context, maxAge, staleWhileRevalidate time.Duration) { _, ok := ctx.GetQuery("skipCache") diff --git a/backend/internal/utils/http_util_test.go b/backend/internal/utils/http_util_test.go deleted file mode 100644 index e0c828b2..00000000 --- a/backend/internal/utils/http_util_test.go +++ /dev/null @@ -1,125 +0,0 @@ -package utils - -import ( - "net/http" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestBearerAuth(t *testing.T) { - tests := []struct { - name string - authHeader string - expectedToken string - expectedFound bool - }{ - { - name: "Valid bearer token", - authHeader: "Bearer token123", - expectedToken: "token123", - expectedFound: true, - }, - { - name: "Valid bearer token with mixed case", - authHeader: "beARer token456", - expectedToken: "token456", - expectedFound: true, - }, - { - name: "No bearer prefix", - authHeader: "Basic dXNlcjpwYXNz", - expectedToken: "", - expectedFound: false, - }, - { - name: "Empty auth header", - authHeader: "", - expectedToken: "", - expectedFound: false, - }, - { - name: "Bearer prefix only", - authHeader: "Bearer ", - expectedToken: "", - expectedFound: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, "http://example.com", nil) - require.NoError(t, err, "Failed to create request") - - if tt.authHeader != "" { - req.Header.Set("Authorization", tt.authHeader) - } - - token, found := BearerAuth(req) - - assert.Equal(t, tt.expectedFound, found) - assert.Equal(t, tt.expectedToken, token) - }) - } -} - -// #nosec G101 - Test credentials -func TestOAuthClientBasicAuth(t *testing.T) { - tests := []struct { - name string - authHeader string - expectedClientID string - expectedClientSecret string - expectedOk bool - }{ - { - name: "Valid client ID and secret in header (example from RFC 6749)", - authHeader: "Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3", - expectedClientID: "s6BhdRkqt3", - expectedClientSecret: "7Fjfp0ZBr1KtDRbnfVdmIw", - expectedOk: true, - }, - { - name: "Valid client ID and secret in header (escaped values)", - authHeader: "Basic ZTUwOTcyYmQtNmUzMi00OTU3LWJhZmMtMzU0MTU3ZjI1NDViOislMjUlMjYlMkIlQzIlQTMlRTIlODIlQUM=", - expectedClientID: "e50972bd-6e32-4957-bafc-354157f2545b", - // This is the example string from RFC 6749, Appendix B. - expectedClientSecret: " %&+£€", - expectedOk: true, - }, - { - name: "Empty auth header", - authHeader: "", - expectedClientID: "", - expectedClientSecret: "", - expectedOk: false, - }, - { - name: "Basic prefix only", - authHeader: "Basic ", - expectedClientID: "", - expectedClientSecret: "", - expectedOk: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, "http://example.com", nil) - require.NoError(t, err, "Failed to create request") - - if tt.authHeader != "" { - req.Header.Set("Authorization", tt.authHeader) - } - - clientId, clientSecret, ok := OAuthClientBasicAuth(req) - - assert.Equal(t, tt.expectedOk, ok) - - if tt.expectedOk { - assert.Equal(t, tt.expectedClientID, clientId) - assert.Equal(t, tt.expectedClientSecret, clientSecret) - } - }) - } -} diff --git a/frontend/messages/en.json b/frontend/messages/en.json index ea6ed82b..4d84fa0a 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -37,8 +37,6 @@ "expiration": "Expiration", "generate_code": "Generate Code", "name": "Name", - "browser_unsupported": "Browser unsupported", - "this_browser_does_not_support_passkeys": "This browser doesn't support passkeys. Please use an alternative sign in method.", "an_unknown_error_occurred": "An unknown error occurred", "authentication_process_was_aborted": "The authentication process was aborted", "error_occurred_with_authenticator": "An error occurred with the authenticator", diff --git a/frontend/package.json b/frontend/package.json index 7fd3a182..7b4a8787 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,7 +19,6 @@ "axios": "^1.16.1", "clsx": "^2.1.1", "date-fns": "^4.2.1", - "jose": "^6.2.3", "qrcode": "^1.5.4", "runed": "^0.37.1", "sveltekit-superforms": "^2.30.1", @@ -35,7 +34,6 @@ "@sveltejs/adapter-static": "^3.0.10", "@sveltejs/kit": "^2.60.1", "@sveltejs/vite-plugin-svelte": "^7.1.2", - "@types/eslint": "^9.6.1", "@types/node": "^25.9.0", "@types/qrcode": "^1.5.6", "bits-ui": "^2.18.1", @@ -48,7 +46,6 @@ "prettier": "^3.8.3", "prettier-plugin-svelte": "^3.5.2", "prettier-plugin-tailwindcss": "^0.8.0", - "rollup": "^4.60.4", "shadcn-svelte": "^1.3.0", "svelte": "^5.55.8", "svelte-check": "^4.4.8", diff --git a/frontend/src/lib/components/form/checkbox-with-label.svelte b/frontend/src/lib/components/form/checkbox-with-label.svelte deleted file mode 100644 index e719d3cc..00000000 --- a/frontend/src/lib/components/form/checkbox-with-label.svelte +++ /dev/null @@ -1,35 +0,0 @@ - - -
- onCheckedChange && onCheckedChange(v == true)} - bind:checked - /> - - {label} - {#if description} - {description} - {/if} - -
diff --git a/frontend/src/lib/components/web-authn-unsupported.svelte b/frontend/src/lib/components/web-authn-unsupported.svelte deleted file mode 100644 index b69a6efc..00000000 --- a/frontend/src/lib/components/web-authn-unsupported.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - -
-
- -
-

{m.browser_unsupported()}

-

- {m.this_browser_does_not_support_passkeys()} -

-
diff --git a/frontend/src/lib/index.ts b/frontend/src/lib/index.ts deleted file mode 100644 index 856f2b6c..00000000 --- a/frontend/src/lib/index.ts +++ /dev/null @@ -1 +0,0 @@ -// place files you want to import through the `$lib` alias in this folder. diff --git a/frontend/src/routes/settings/admin/oidc-clients/client-secret.svelte b/frontend/src/routes/settings/admin/oidc-clients/client-secret.svelte deleted file mode 100644 index f7b939b6..00000000 --- a/frontend/src/routes/settings/admin/oidc-clients/client-secret.svelte +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - {m.one_time_link()} - {m.use_this_link_to_sign_in_once()} - - {m.one_time_link()} - - - diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 26eb8d88..e3758e74 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -76,9 +76,6 @@ importers: date-fns: specifier: ^4.2.1 version: 4.4.0 - jose: - specifier: ^6.2.3 - version: 6.2.3 qrcode: specifier: ^1.5.4 version: 1.5.4 @@ -119,9 +116,6 @@ importers: '@sveltejs/vite-plugin-svelte': specifier: ^7.1.2 version: 7.1.2(svelte@5.56.3(@typescript-eslint/types@8.61.0))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.0)(tsx@4.22.4)(yaml@2.9.0)) - '@types/eslint': - specifier: ^9.6.1 - version: 9.6.1 '@types/node': specifier: ^25.9.0 version: 25.9.3 @@ -158,9 +152,6 @@ importers: prettier-plugin-tailwindcss: specifier: ^0.8.0 version: 0.8.0(prettier-plugin-svelte@3.5.2(prettier@3.8.4)(svelte@5.56.3(@typescript-eslint/types@8.61.0)))(prettier@3.8.4) - rollup: - specifier: ^4.60.4 - version: 4.61.1 shadcn-svelte: specifier: ^1.3.0 version: 1.3.0(svelte@5.56.3(@typescript-eslint/types@8.61.0)) @@ -1241,144 +1232,6 @@ packages: '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - '@rollup/rollup-android-arm-eabi@4.61.1': - resolution: {integrity: sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.61.1': - resolution: {integrity: sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.61.1': - resolution: {integrity: sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.61.1': - resolution: {integrity: sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.61.1': - resolution: {integrity: sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.61.1': - resolution: {integrity: sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.61.1': - resolution: {integrity: sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==} - cpu: [arm] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm-musleabihf@4.61.1': - resolution: {integrity: sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==} - cpu: [arm] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-arm64-gnu@4.61.1': - resolution: {integrity: sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm64-musl@4.61.1': - resolution: {integrity: sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-loong64-gnu@4.61.1': - resolution: {integrity: sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==} - cpu: [loong64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-loong64-musl@4.61.1': - resolution: {integrity: sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==} - cpu: [loong64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-ppc64-gnu@4.61.1': - resolution: {integrity: sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-ppc64-musl@4.61.1': - resolution: {integrity: sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==} - cpu: [ppc64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-riscv64-gnu@4.61.1': - resolution: {integrity: sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-riscv64-musl@4.61.1': - resolution: {integrity: sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-s390x-gnu@4.61.1': - resolution: {integrity: sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-gnu@4.61.1': - resolution: {integrity: sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-musl@4.61.1': - resolution: {integrity: sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rollup/rollup-openbsd-x64@4.61.1': - resolution: {integrity: sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.61.1': - resolution: {integrity: sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.61.1': - resolution: {integrity: sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.61.1': - resolution: {integrity: sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.61.1': - resolution: {integrity: sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.61.1': - resolution: {integrity: sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==} - cpu: [x64] - os: [win32] - '@selderee/plugin-htmlparser2@0.11.0': resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==} @@ -1556,9 +1409,6 @@ packages: '@types/cors@2.8.19': resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} - '@types/eslint@9.6.1': - resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} - '@types/esrecurse@4.3.1': resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} @@ -2846,11 +2696,6 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - rollup@4.61.1: - resolution: {integrity: sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - runed@0.23.4: resolution: {integrity: sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA==} peerDependencies: @@ -4071,81 +3916,6 @@ snapshots: '@rolldown/pluginutils@1.0.1': {} - '@rollup/rollup-android-arm-eabi@4.61.1': - optional: true - - '@rollup/rollup-android-arm64@4.61.1': - optional: true - - '@rollup/rollup-darwin-arm64@4.61.1': - optional: true - - '@rollup/rollup-darwin-x64@4.61.1': - optional: true - - '@rollup/rollup-freebsd-arm64@4.61.1': - optional: true - - '@rollup/rollup-freebsd-x64@4.61.1': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.61.1': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.61.1': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.61.1': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.61.1': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.61.1': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.61.1': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.61.1': - optional: true - - '@rollup/rollup-linux-ppc64-musl@4.61.1': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.61.1': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.61.1': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.61.1': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.61.1': - optional: true - - '@rollup/rollup-linux-x64-musl@4.61.1': - optional: true - - '@rollup/rollup-openbsd-x64@4.61.1': - optional: true - - '@rollup/rollup-openharmony-arm64@4.61.1': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.61.1': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.61.1': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.61.1': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.61.1': - optional: true - '@selderee/plugin-htmlparser2@0.11.0': dependencies: domhandler: 5.0.3 @@ -4302,11 +4072,6 @@ snapshots: dependencies: '@types/node': 25.9.3 - '@types/eslint@9.6.1': - dependencies: - '@types/estree': 1.0.9 - '@types/json-schema': 7.0.15 - '@types/esrecurse@4.3.1': {} '@types/estree@1.0.9': {} @@ -5556,37 +5321,6 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.3 '@rolldown/binding-win32-x64-msvc': 1.0.3 - rollup@4.61.1: - dependencies: - '@types/estree': 1.0.9 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.61.1 - '@rollup/rollup-android-arm64': 4.61.1 - '@rollup/rollup-darwin-arm64': 4.61.1 - '@rollup/rollup-darwin-x64': 4.61.1 - '@rollup/rollup-freebsd-arm64': 4.61.1 - '@rollup/rollup-freebsd-x64': 4.61.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.61.1 - '@rollup/rollup-linux-arm-musleabihf': 4.61.1 - '@rollup/rollup-linux-arm64-gnu': 4.61.1 - '@rollup/rollup-linux-arm64-musl': 4.61.1 - '@rollup/rollup-linux-loong64-gnu': 4.61.1 - '@rollup/rollup-linux-loong64-musl': 4.61.1 - '@rollup/rollup-linux-ppc64-gnu': 4.61.1 - '@rollup/rollup-linux-ppc64-musl': 4.61.1 - '@rollup/rollup-linux-riscv64-gnu': 4.61.1 - '@rollup/rollup-linux-riscv64-musl': 4.61.1 - '@rollup/rollup-linux-s390x-gnu': 4.61.1 - '@rollup/rollup-linux-x64-gnu': 4.61.1 - '@rollup/rollup-linux-x64-musl': 4.61.1 - '@rollup/rollup-openbsd-x64': 4.61.1 - '@rollup/rollup-openharmony-arm64': 4.61.1 - '@rollup/rollup-win32-arm64-msvc': 4.61.1 - '@rollup/rollup-win32-ia32-msvc': 4.61.1 - '@rollup/rollup-win32-x64-gnu': 4.61.1 - '@rollup/rollup-win32-x64-msvc': 4.61.1 - fsevents: 2.3.3 - runed@0.23.4(svelte@5.56.3(@typescript-eslint/types@8.61.0)): dependencies: esm-env: 1.2.2