From 1123d7b98c23d5ec0d17a748af55e4348b25ee56 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 12 Oct 2022 15:11:45 +0200 Subject: [PATCH 01/93] introduce functionality to assign/create team via group claim --- pkg/models/teams.go | 61 ++++++++++++++++++++++++++- pkg/modules/auth/openid/openid.go | 69 ++++++++++++++++++++++++++++--- 2 files changed, 124 insertions(+), 6 deletions(-) diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 1b3deea8b..49e56d68f 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -79,7 +79,7 @@ type TeamMember struct { } // TableName makes beautiful table names -func (*TeamMember) TableName() string { +func (TeamMember) TableName() string { return "team_members" } @@ -119,6 +119,34 @@ func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) { return } +func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { + if name == "" { + return teams, ErrTeamsDoNotExist{name} + } + + var ts []*Team + + exists := s. + Where("name = ?", name). + Find(&ts) + if exists != nil { + return + } + if len(ts) == 0 { + return ts, ErrTeamsDoNotExist{name} + } + + // //for each ts + // teamSlice := []*Team{ts} + // err = addMoreInfoToTeams(s, teamSlice) + // if err != nil { + // return + // } + + teams = ts + + return +} func addMoreInfoToTeams(s *xorm.Session, teams []*Team) (err error) { @@ -282,6 +310,37 @@ func (t *Team) Create(s *xorm.Session, a web.Auth) (err error) { }) } +func (t *Team) CreateNoAdmin(s *xorm.Session, a web.Auth) (err error) { + doer, err := user.GetFromAuth(a) + if err != nil { + return err + } + + // Check if we have a name + if t.Name == "" { + return ErrTeamNameCannotBeEmpty{} + } + + t.CreatedByID = doer.ID + t.CreatedBy = doer + + _, err = s.Insert(t) + if err != nil { + return + } + + // Insert the current user as member and admin + tm := TeamMember{TeamID: t.ID, Username: doer.Username, Admin: false} + if err = tm.Create(s, doer); err != nil { + return err + } + + return events.Dispatch(&TeamCreatedEvent{ + Team: t, + Doer: a, + }) +} + // Delete deletes a team // @Summary Deletes a team // @Description Delets a team. This will also remove the access for all users in that team. diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 618dcd531..afec5b30c 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -53,16 +53,18 @@ type Provider struct { AuthURL string `json:"auth_url"` LogoutURL string `json:"logout_url"` ClientID string `json:"client_id"` + Scope string `json:"scope"` ClientSecret string `json:"-"` openIDProvider *oidc.Provider Oauth2Config *oauth2.Config `json:"-"` } type claims struct { - Email string `json:"email"` - Name string `json:"name"` - PreferredUsername string `json:"preferred_username"` - Nickname string `json:"nickname"` + Email string `json:"email"` + Name string `json:"name"` + PreferredUsername string `json:"preferred_username"` + Nickname string `json:"nickname"` + Group []string `json:"groups"` } func init() { @@ -192,22 +194,79 @@ func HandleCallback(c echo.Context) error { // Check if we have seen this user before u, err := getOrCreateUser(s, cl, idToken.Issuer, idToken.Subject) + + log.Errorf("Issuer %s: %v", idToken.Issuer, err) + if err != nil { _ = s.Rollback() log.Errorf("Error creating new user for provider %s: %v", provider.Name, err) return handler.HandleHTTPError(err, c) } + // Check if we have seen this user before + teams, err := GetOrCreateTeamsByNames(s, cl.Group, u) + if err != nil { + log.Errorf("Error verifying team for name %v, got %v", cl.Name, teams, err) + return err + } else { + for _, team := range teams { + tm := models.TeamMember{TeamID: team.ID, Username: u.Username} + if err = tm.Create(s, u); err != nil { + switch t := err.(type) { + case *models.ErrUserIsMemberOfTeam: + log.Errorf("ErrUserIsMemberOfTeam", t) + break + default: + log.Errorf("Error assigning User to team", t) + } + } + } + } + err = s.Commit() if err != nil { return handler.HandleHTTPError(err, c) } - // Create token return auth.NewUserAuthTokenResponse(u, c, false) } +func GetOrCreateTeamsByNames(s *xorm.Session, teamNames []string, u *user.User) (te []models.Team, err error) { + te = []models.Team{} + for _, t := range teamNames { + team, err := models.GetTeamsByName(s, t) + + if models.IsErrTeamsDoNotExist(err) { + log.Errorf("No such Team: %v, got %v", t, team, err) + tea := &models.Team{ + Name: t, + } + err := tea.CreateNoAdmin(s, u) + if err != nil { + log.Errorf("Teams: %v, err: %v", tea, err) + } else { + te = append(te, *tea) + } + } else { + // if multiple teams with same name are found, + if len(team) == 1 { + te = append(te, *team[len(team)-1]) + } else { + log.Errorf("Multiple Teams have the same name: %v, ", team[len(team)-1].Name) + } + } + } + return te, err +} + +// assign user to team +// remove user from team if not in group +// if multiple teams found with same name -> do nothing +// optional: assign by id +// + func getOrCreateUser(s *xorm.Session, cl *claims, issuer, subject string) (u *user.User, err error) { + // Check if the user exists for that issuer and subject u, err = user.GetUserWithEmail(s, &user.User{ Issuer: issuer, -- 2.45.1 From 97b13eecf3d7669019c1856cf8479d6697829195 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 7 Dec 2022 15:32:58 +0100 Subject: [PATCH 02/93] wip assign groups via oidc --- pkg/models/team_members.go | 22 ++++++++++++++- pkg/models/teams.go | 45 +++++-------------------------- pkg/modules/auth/openid/openid.go | 40 +++++++++++++-------------- 3 files changed, 46 insertions(+), 61 deletions(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index 829661214..8db8c4fa5 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -18,6 +18,7 @@ package models import ( "code.vikunja.io/api/pkg/events" + "code.vikunja.io/api/pkg/log" user2 "code.vikunja.io/api/pkg/user" "code.vikunja.io/web" "xorm.io/xorm" @@ -54,7 +55,7 @@ func (tm *TeamMember) Create(s *xorm.Session, a web.Auth) (err error) { // Check if that user is already part of the team exists, err := s. - Where("team_id = ? AND user_id = ?", tm.TeamID, tm.UserID). + Where("team_id = ? AND user_name = ?", tm.TeamID, tm.UserID). Get(&TeamMember{}) if err != nil { return @@ -109,6 +110,25 @@ func (tm *TeamMember) Delete(s *xorm.Session, _ web.Auth) (err error) { return } +func (tm *TeamMember) CheckMembership(s *xorm.Session) (err error) { + member, err := user2.GetUserByUsername(s, tm.Username) + if err != nil { + return + } + tm.UserID = member.ID + exists, err := s. + Where("team_id = ? AND user_id = ?", tm.TeamID, tm.UserID). + Get(&TeamMember{}) + if err != nil { + return + } + if exists { + log.Errorf("Team member already exists %v", ErrUserIsMemberOfTeam{tm.UserID, tm.UserID}) + return ErrUserIsMemberOfTeam{tm.UserID, tm.UserID} + } + return +} + // Update toggles a team member's admin status // @Summary Toggle a team member's admin status // @Description If a user is team admin, this will make them member and vise-versa. diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 49e56d68f..69b29edc4 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -119,6 +119,8 @@ func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) { return } + +// GetTeamByID gets teams by name func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { if name == "" { return teams, ErrTeamsDoNotExist{name} @@ -135,14 +137,6 @@ func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { if len(ts) == 0 { return ts, ErrTeamsDoNotExist{name} } - - // //for each ts - // teamSlice := []*Team{ts} - // err = addMoreInfoToTeams(s, teamSlice) - // if err != nil { - // return - // } - teams = ts return @@ -298,8 +292,9 @@ func (t *Team) Create(s *xorm.Session, a web.Auth) (err error) { return } - // Insert the current user as member and admin - tm := TeamMember{TeamID: t.ID, Username: doer.Username, Admin: true} + var admin bool = true + // } + tm := TeamMember{TeamID: t.ID, Username: doer.Username, Admin: admin} if err = tm.Create(s, doer); err != nil { return err } @@ -310,35 +305,9 @@ func (t *Team) Create(s *xorm.Session, a web.Auth) (err error) { }) } -func (t *Team) CreateNoAdmin(s *xorm.Session, a web.Auth) (err error) { - doer, err := user.GetFromAuth(a) - if err != nil { - return err - } - - // Check if we have a name - if t.Name == "" { - return ErrTeamNameCannotBeEmpty{} - } - - t.CreatedByID = doer.ID - t.CreatedBy = doer - - _, err = s.Insert(t) - if err != nil { - return - } - +func (t *Team) ManageAdminRight(teamMember TeamMember, admin bool) { // Insert the current user as member and admin - tm := TeamMember{TeamID: t.ID, Username: doer.Username, Admin: false} - if err = tm.Create(s, doer); err != nil { - return err - } - - return events.Dispatch(&TeamCreatedEvent{ - Team: t, - Doer: a, - }) + teamMember.Admin = admin } // Delete deletes a team diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index afec5b30c..1ab7f28ea 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -64,7 +64,7 @@ type claims struct { Name string `json:"name"` PreferredUsername string `json:"preferred_username"` Nickname string `json:"nickname"` - Group []string `json:"groups"` + Teams []string `json:"groups"` } func init() { @@ -195,34 +195,28 @@ func HandleCallback(c echo.Context) error { // Check if we have seen this user before u, err := getOrCreateUser(s, cl, idToken.Issuer, idToken.Subject) - log.Errorf("Issuer %s: %v", idToken.Issuer, err) - if err != nil { _ = s.Rollback() log.Errorf("Error creating new user for provider %s: %v", provider.Name, err) return handler.HandleHTTPError(err, c) } - // Check if we have seen this user before - teams, err := GetOrCreateTeamsByNames(s, cl.Group, u) - if err != nil { - log.Errorf("Error verifying team for name %v, got %v", cl.Name, teams, err) - return err - } else { - for _, team := range teams { - tm := models.TeamMember{TeamID: team.ID, Username: u.Username} - if err = tm.Create(s, u); err != nil { - switch t := err.(type) { - case *models.ErrUserIsMemberOfTeam: - log.Errorf("ErrUserIsMemberOfTeam", t) - break - default: - log.Errorf("Error assigning User to team", t) + // Check if we have seen these teams before + if len(cl.Teams) > 0 { + teams, err := GetOrCreateTeamsByNames(s, cl.Teams, u) + if err != nil { + log.Errorf("Error verifying team for name %v, got %v", cl.Name, teams, err) + return err + } else { + for _, team := range teams { + tm := models.TeamMember{TeamID: team.ID, Username: u.Username} + err := tm.CheckMembership(s) + if err == nil { + tm.Create(s, u) } } } } - err = s.Commit() if err != nil { return handler.HandleHTTPError(err, c) @@ -236,12 +230,13 @@ func GetOrCreateTeamsByNames(s *xorm.Session, teamNames []string, u *user.User) for _, t := range teamNames { team, err := models.GetTeamsByName(s, t) + // if team does not exists, create it if models.IsErrTeamsDoNotExist(err) { - log.Errorf("No such Team: %v, got %v", t, team, err) + log.Debugf("No such Team: %v, create %v ..", t, team) tea := &models.Team{ Name: t, } - err := tea.CreateNoAdmin(s, u) + err := tea.Create(s, u) if err != nil { log.Errorf("Teams: %v, err: %v", tea, err) } else { @@ -250,9 +245,10 @@ func GetOrCreateTeamsByNames(s *xorm.Session, teamNames []string, u *user.User) } else { // if multiple teams with same name are found, if len(team) == 1 { + // append team to return value te = append(te, *team[len(team)-1]) } else { - log.Errorf("Multiple Teams have the same name: %v, ", team[len(team)-1].Name) + log.Debugf("Multiple Teams have the same name: %v, ignore assignment of %v", team[len(team)-1].Name, u.Name) } } } -- 2.45.1 From a4c8672a80a62909c54f67e330525fbd4e93a3e7 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:13:33 +0100 Subject: [PATCH 03/93] migration to add idcID to teams --- pkg/migration/20230104152903.go | 43 +++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 pkg/migration/20230104152903.go diff --git a/pkg/migration/20230104152903.go b/pkg/migration/20230104152903.go new file mode 100644 index 000000000..8991ddd89 --- /dev/null +++ b/pkg/migration/20230104152903.go @@ -0,0 +1,43 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-2021 Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public Licensee as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public Licensee for more details. +// +// You should have received a copy of the GNU Affero General Public Licensee +// along with this program. If not, see . + +package migration + +import ( + "src.techknowlogick.com/xormigrate" + "xorm.io/xorm" +) + +type teams20230104152903 struct { + OidcID string `xorm:"varchar(250) null" maxLength:"250" json:"oidc_id"` +} + +func (teams20230104152903) TableName() string { + return "teams" +} + +func init() { + migrations = append(migrations, &xormigrate.Migration{ + ID: "20230104152903", + Description: "Adding OidcID to teams", + Migrate: func(tx *xorm.Engine) error { + return tx.Sync2(teams20230104152903{}) + }, + Rollback: func(tx *xorm.Engine) error { + return nil + }, + }) +} -- 2.45.1 From 1c6553940e92e6f0864dc495613d0b0e78547dce Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:22:42 +0100 Subject: [PATCH 04/93] add errors to user --- pkg/user/error.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pkg/user/error.go b/pkg/user/error.go index cb73f06d4..26deaa4cb 100644 --- a/pkg/user/error.go +++ b/pkg/user/error.go @@ -426,6 +426,32 @@ func (err *ErrNoOpenIDEmailProvided) HTTPError() web.HTTPError { } } +// ErrNoOpenIDEmailProvided represents a "NoEmailProvided" kind of error. +type ErrOpenIDCustomScopeMalformed struct { +} + +// IsErrNoEmailProvided checks if an error is a ErrNoOpenIDEmailProvided. +func IsErrOpenIDCustomScopeMalformed(err error) bool { + _, ok := err.(*ErrOpenIDCustomScopeMalformed) + return ok +} + +func (err *ErrOpenIDCustomScopeMalformed) Error() string { + return "Custom Scope malformed" +} + +// ErrCodeNoOpenIDEmailProvided holds the unique world-error code of this error +const ErrCodeOpenIDCustomScopeMalformed = 1022 + +// HTTPError holds the http error description +func (err *ErrOpenIDCustomScopeMalformed) HTTPError() web.HTTPError { + return web.HTTPError{ + HTTPCode: http.StatusPreconditionFailed, + Code: ErrCodeOpenIDCustomScopeMalformed, + Message: "The custom scope set by the OIDC provider is malformed. Please make sure the openid provider sets the data correctly for your scope. Check especially to have set an oidcID", + } +} + // ErrAccountDisabled represents a "AccountDisabled" kind of error. type ErrAccountDisabled struct { UserID int64 -- 2.45.1 From 7fb896829915fe9079d65f95def85a7e81bd5154 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:31:43 +0100 Subject: [PATCH 05/93] add OidcIDto teams --- pkg/models/team_members.go | 15 +++++---------- pkg/models/teams.go | 3 +++ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index 8db8c4fa5..933545336 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -18,7 +18,6 @@ package models import ( "code.vikunja.io/api/pkg/events" - "code.vikunja.io/api/pkg/log" user2 "code.vikunja.io/api/pkg/user" "code.vikunja.io/web" "xorm.io/xorm" @@ -55,7 +54,7 @@ func (tm *TeamMember) Create(s *xorm.Session, a web.Auth) (err error) { // Check if that user is already part of the team exists, err := s. - Where("team_id = ? AND user_name = ?", tm.TeamID, tm.UserID). + Where("team_id = ? AND user_id = ?", tm.TeamID, tm.UserID). Get(&TeamMember{}) if err != nil { return @@ -110,23 +109,19 @@ func (tm *TeamMember) Delete(s *xorm.Session, _ web.Auth) (err error) { return } -func (tm *TeamMember) CheckMembership(s *xorm.Session) (err error) { +func (tm *TeamMember) CheckMembership(s *xorm.Session) (exists bool, err error) { member, err := user2.GetUserByUsername(s, tm.Username) if err != nil { return } tm.UserID = member.ID - exists, err := s. + exists, err = s. Where("team_id = ? AND user_id = ?", tm.TeamID, tm.UserID). Get(&TeamMember{}) - if err != nil { + if exists { return } - if exists { - log.Errorf("Team member already exists %v", ErrUserIsMemberOfTeam{tm.UserID, tm.UserID}) - return ErrUserIsMemberOfTeam{tm.UserID, tm.UserID} - } - return + return exists, ErrUserIsMemberOfTeam{tm.UserID, tm.UserID} } // Update toggles a team member's admin status diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 69b29edc4..b94a84351 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -20,6 +20,7 @@ import ( "time" "code.vikunja.io/api/pkg/db" + "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/events" "code.vikunja.io/api/pkg/user" @@ -38,6 +39,8 @@ type Team struct { // The team's description. Description string `xorm:"longtext null" json:"description"` CreatedByID int64 `xorm:"bigint not null INDEX" json:"-"` + // The team's oidc id delivered by the oidc provider + OidcID string `xorm:"varchar(250) null" maxLength:"250" json:"oidc_id"` // The user who created this team. CreatedBy *user.User `xorm:"-" json:"created_by"` -- 2.45.1 From 27eb746b98e3a0955f8595b79587395a29a95848 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:33:45 +0100 Subject: [PATCH 06/93] add functionality of searching teams by oidcId and name to teams.go --- pkg/models/teams.go | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/pkg/models/teams.go b/pkg/models/teams.go index b94a84351..386d15af0 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -123,7 +123,7 @@ func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) { return } -// GetTeamByID gets teams by name +// GetTeamByName gets teams by name func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { if name == "" { return teams, ErrTeamsDoNotExist{name} @@ -131,18 +131,28 @@ func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { var ts []*Team - exists := s. + err = s. Where("name = ?", name). Find(&ts) - if exists != nil { - return - } - if len(ts) == 0 { + if err != nil || len(ts) == 0 { return ts, ErrTeamsDoNotExist{name} } teams = ts + return teams, err +} - return +// GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters +// For oidc team creation oidcID and Name need to be set +func GetTeamByOidcIDAndName(s *xorm.Session, id string, name string) (team Team, err error) { + exists, err := s. + Table("teams"). + Where("oidc_id = ? AND name = ?", id, name). + Get(&team) + log.Debugf("GetTeamByOidcIDAndName: %v, exists: %v", team.Name, exists) + if exists && err == nil { + return team, nil + } + return team, ErrTeamsDoNotExist{id} } func addMoreInfoToTeams(s *xorm.Session, teams []*Team) (err error) { @@ -295,8 +305,7 @@ func (t *Team) Create(s *xorm.Session, a web.Auth) (err error) { return } - var admin bool = true - // } + var admin = true tm := TeamMember{TeamID: t.ID, Username: doer.Username, Admin: admin} if err = tm.Create(s, doer); err != nil { return err -- 2.45.1 From f5c872d99b3dd74aa8a5860f7f978ddff508049c Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:36:04 +0100 Subject: [PATCH 07/93] add scope to provider --- pkg/modules/auth/openid/providers.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/modules/auth/openid/providers.go b/pkg/modules/auth/openid/providers.go index 8791491f5..f045d19d3 100644 --- a/pkg/modules/auth/openid/providers.go +++ b/pkg/modules/auth/openid/providers.go @@ -132,6 +132,7 @@ func getProviderFromMap(pi map[string]interface{}) (provider *Provider, err erro OriginalAuthURL: pi["authurl"].(string), ClientSecret: pi["clientsecret"].(string), LogoutURL: logoutURL, + Scope: pi["scope"].(string), } cl, is := pi["clientid"].(int) -- 2.45.1 From 7edcf1a24f37079378881c2dfcdf174851f5c7de Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:40:35 +0100 Subject: [PATCH 08/93] add VikunjaGroups to claums struct in openid.go --- pkg/modules/auth/openid/openid.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 1ab7f28ea..528c0c546 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -58,13 +58,13 @@ type Provider struct { openIDProvider *oidc.Provider Oauth2Config *oauth2.Config `json:"-"` } - type claims struct { - Email string `json:"email"` - Name string `json:"name"` - PreferredUsername string `json:"preferred_username"` - Nickname string `json:"nickname"` - Teams []string `json:"groups"` + Email string `json:"email"` + Name string `json:"name"` + PreferredUsername string `json:"preferred_username"` + Nickname string `json:"nickname"` + Teams []string `json:"groups"` + VikunjaGroups interface{} `json:"vikunja_groups"` } func init() { -- 2.45.1 From dbc4970716f7b23ffc337185f3ba04fe535937fb Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:41:30 +0100 Subject: [PATCH 09/93] add TeamData struct to openid.go --- pkg/modules/auth/openid/openid.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 528c0c546..37ae5cb6e 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -58,6 +58,11 @@ type Provider struct { openIDProvider *oidc.Provider Oauth2Config *oauth2.Config `json:"-"` } +type TeamData struct { + TeamName string + OidcID string + Description string +} type claims struct { Email string `json:"email"` Name string `json:"name"` -- 2.45.1 From c5271499545d7b70504dd42350b82706e257f992 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:49:19 +0100 Subject: [PATCH 10/93] add functionality to assign user to teams through oidc custom claim --- pkg/modules/auth/openid/openid.go | 123 ++++++++++++++++++++++-------- 1 file changed, 92 insertions(+), 31 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 37ae5cb6e..a37bbde5b 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -152,6 +152,7 @@ func HandleCallback(c echo.Context) error { // Extract custom claims cl := &claims{} + err = idToken.Claims(cl) if err != nil { log.Errorf("Error getting token claims for provider %s: %v", provider.Name, err) @@ -206,57 +207,117 @@ func HandleCallback(c echo.Context) error { return handler.HandleHTTPError(err, c) } - // Check if we have seen these teams before - if len(cl.Teams) > 0 { - teams, err := GetOrCreateTeamsByNames(s, cl.Teams, u) + // does the oidc token contain well formed "vikunja_groups" through vikunja_scope + teamData, err := getTeamDataFromToken(cl.VikunjaGroups, provider) + if err != nil { + log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) + return handler.HandleHTTPError(err, c) + } + // check if we have seen these teams before. + // find or create Teams and assign user as teammember. + if len(teamData) > 0 { + log.Debugf("TeamData is set %v", teamData) + teams, err := GetOrCreateTeamsByNames(s, teamData, u) if err != nil { log.Errorf("Error verifying team for name %v, got %v", cl.Name, teams, err) return err - } else { - for _, team := range teams { - tm := models.TeamMember{TeamID: team.ID, Username: u.Username} - err := tm.CheckMembership(s) - if err == nil { - tm.Create(s, u) + } + + for _, team := range teams { + tm := models.TeamMember{TeamID: team.ID, Username: u.Username} + exists, err := tm.CheckMembership(s) + if !exists { + err = tm.Create(s, u) + if err != nil { + log.Debugf("Could not assign %v to %v. %v", u.Username, team.Name, err) } + } else { + log.Debugf("Team exists? %v or error: %v", exists, err) } } } + err = s.Commit() if err != nil { + _ = s.Rollback() + log.Errorf("Error creating new Team for provider %s: %v", provider.Name, err) return handler.HandleHTTPError(err, c) } // Create token return auth.NewUserAuthTokenResponse(u, c, false) } -func GetOrCreateTeamsByNames(s *xorm.Session, teamNames []string, u *user.User) (te []models.Team, err error) { - te = []models.Team{} - for _, t := range teamNames { - team, err := models.GetTeamsByName(s, t) - - // if team does not exists, create it - if models.IsErrTeamsDoNotExist(err) { - log.Debugf("No such Team: %v, create %v ..", t, team) - tea := &models.Team{ - Name: t, +func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []TeamData, err error) { + teamData = []TeamData{} + if groups != nil { + el := groups.([]interface{}) + for _, data := range el { + team := data.(map[string]interface{}) + log.Debugf("%s", team) + var name string + var description string + var oidcID string + if team["name"] != nil { + name = team["name"].(string) } - err := tea.Create(s, u) - if err != nil { - log.Errorf("Teams: %v, err: %v", tea, err) - } else { - te = append(te, *tea) + if team["description"] != nil { + description = team["description"].(string) } - } else { - // if multiple teams with same name are found, - if len(team) == 1 { - // append team to return value - te = append(te, *team[len(team)-1]) - } else { - log.Debugf("Multiple Teams have the same name: %v, ignore assignment of %v", team[len(team)-1].Name, u.Name) + if team["oidcID"] != nil { + switch t := team["oidcID"].(type) { + case int64: + oidcID = fmt.Sprintf("%v", team["oidcID"]) + case string: + oidcID = string(team["oidcID"].(string)) + case float64: + fl := float64(team["oidcID"].(float64)) + oidcID = fmt.Sprintf("%v", fl) + default: + log.Errorf("No oidcID assigned for %v or type %v not supported", team, t) + } } + if name == "" || oidcID == "" { + log.Errorf("Claim of your custom scope does not hold name or oidcID for automatic group assignment through oidc provider. Please check %s", provider.Name) + return teamData, &user.ErrOpenIDCustomScopeMalformed{} + } + teamData = append(teamData, TeamData{TeamName: name, OidcID: oidcID, Description: description}) } } + return teamData, nil +} + +func CreateTeamWithData(s *xorm.Session, teamData TeamData, u *user.User) (team *models.Team, err error) { + tea := &models.Team{ + Name: teamData.TeamName, + Description: teamData.Description, + OidcID: teamData.OidcID, + } + log.Debugf("Teams: %v", tea.OidcID) + + err = tea.Create(s, u) + return tea, err +} + +// this functions creates an array of existing teams that was generated from the oidc data. +func GetOrCreateTeamsByNames(s *xorm.Session, teamData []TeamData, u *user.User) (te []models.Team, err error) { + te = []models.Team{} + // Procedure can only be successful if oidcID is set and converted to string + for _, oidcTeam := range teamData { + team, err := models.GetTeamByOidcIDAndName(s, oidcTeam.OidcID, oidcTeam.TeamName) + if err != nil { + log.Debugf("Team with oidc_id %v and name %v does not exist. Create Team.. ", oidcTeam.OidcID, oidcTeam.TeamName) + newTeam, err := CreateTeamWithData(s, oidcTeam, u) + if err != nil { + return te, err + } + te = append(te, *newTeam) + } else { + log.Debugf("Team with oidc_id %v and name %v already exists.", team.OidcID, team.Name) + te = append(te, team) + } + + } + log.Debugf("Array: %v", te) return te, err } -- 2.45.1 From 108c8daf2430eda336a8b88d6299467d554eb9b2 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 16:53:14 +0100 Subject: [PATCH 11/93] change method function to GetOrCreateTeamsByOIDCAndNames --- pkg/modules/auth/openid/openid.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index a37bbde5b..e3291ec8c 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -217,7 +217,7 @@ func HandleCallback(c echo.Context) error { // find or create Teams and assign user as teammember. if len(teamData) > 0 { log.Debugf("TeamData is set %v", teamData) - teams, err := GetOrCreateTeamsByNames(s, teamData, u) + teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u) if err != nil { log.Errorf("Error verifying team for name %v, got %v", cl.Name, teams, err) return err @@ -299,7 +299,7 @@ func CreateTeamWithData(s *xorm.Session, teamData TeamData, u *user.User) (team } // this functions creates an array of existing teams that was generated from the oidc data. -func GetOrCreateTeamsByNames(s *xorm.Session, teamData []TeamData, u *user.User) (te []models.Team, err error) { +func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []TeamData, u *user.User) (te []models.Team, err error) { te = []models.Team{} // Procedure can only be successful if oidcID is set and converted to string for _, oidcTeam := range teamData { -- 2.45.1 From a96dc36d586dd05e6f3200baaa888ac43e3dbdf2 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 17:15:50 +0100 Subject: [PATCH 12/93] add functionality for deleting user only from oidc teams which are not present in the current token --- pkg/models/error.go | 46 +++++++++++++++++++++++++- pkg/models/teams.go | 26 +++++++++++++-- pkg/modules/auth/openid/openid.go | 54 ++++++++++++++++++++++++++++--- 3 files changed, 117 insertions(+), 9 deletions(-) diff --git a/pkg/models/error.go b/pkg/models/error.go index b20267b55..4cf44d8c8 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1059,7 +1059,6 @@ func (err ErrTeamNameCannotBeEmpty) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeTeamNameCannotBeEmpty, Message: "The team name cannot be empty"} } -// ErrTeamDoesNotExist represents an error where a team does not exist type ErrTeamDoesNotExist struct { TeamID int64 } @@ -1178,6 +1177,51 @@ func (err ErrTeamDoesNotHaveAccessToProject) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusForbidden, Code: ErrCodeTeamDoesNotHaveAccessToProject, Message: "This team does not have access to the project."} } +type ErrTeamsDoNotExist struct { + Name string +} + +// IsErrTeamDoNotExist checks if an error is ErrTeamDoesNotExist. +func IsErrTeamsDoNotExist(err error) bool { + _, ok := err.(ErrTeamsDoNotExist) + return ok +} + +func (err ErrTeamsDoNotExist) Error() string { + return fmt.Sprintf("Team does not exist [Team Name: %v]", err.Name) +} + +// ErrCodeTeamDoesNotExist holds the unique world-error code of this error +const ErrCodeTeamsDoNotExist = 6008 + +// HTTPError holds the http error description +func (err ErrTeamsDoNotExist) HTTPError() web.HTTPError { + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No team with given name exists."} +} + +// ErrOIDCTeamsDoNotExistForUser represents an error where an oidcTeam does not exist for the user +type ErrOIDCTeamsDoNotExistForUser struct { + UserID int64 +} + +// IsErrOIDCTeamsDoNotExistForUser checks if an error is ErrOIDCTeamsDoNotExistForUser. +func IsErrOIDCTeamsDoNotExistForUser(err error) bool { + _, ok := err.(ErrTeamDoesNotExist) + return ok +} + +func (err ErrOIDCTeamsDoNotExistForUser) Error() string { + return fmt.Sprintf("No Oidc exists for User [User ID: %d]", err.UserID) +} + +// ErrCodeTeamDoesNotExist holds the unique world-error code of this error +const ErrCodeOIDCTeamsDoNotExistForUser = 6009 + +// HTTPError holds the http error description +func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError { + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "This team does not exist."} +} + // ==================== // User <-> Project errors // ==================== diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 386d15af0..7aeccd03a 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -94,6 +94,12 @@ type TeamUser struct { TeamID int64 `json:"-"` } +type TeamData struct { + TeamName string + OidcID string + Description string +} + // GetTeamByID gets a team by its ID func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) { if id < 1 { @@ -143,16 +149,30 @@ func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { // GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters // For oidc team creation oidcID and Name need to be set -func GetTeamByOidcIDAndName(s *xorm.Session, id string, name string) (team Team, err error) { +func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (team Team, err error) { exists, err := s. Table("teams"). - Where("oidc_id = ? AND name = ?", id, name). + Where("oidc_id = ? AND name = ?", oidcID, teamName). Get(&team) log.Debugf("GetTeamByOidcIDAndName: %v, exists: %v", team.Name, exists) if exists && err == nil { return team, nil } - return team, ErrTeamsDoNotExist{id} + return team, ErrTeamsDoNotExist{oidcID} +} + +func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err error) { + err = s. + Table("team_members"). + Where("user_id = ? ", userID). + Join("RIGHT", "teams", "teams.id = team_members.team_id"). + Where("teams.oidc_id != ?", ""). + Cols("teams.id"). + Find(&ts) + if ts == nil || err != nil { + return ts, ErrOIDCTeamsDoNotExistForUser{userID} + } + return ts, nil } func addMoreInfoToTeams(s *xorm.Session, teams []*Team) (err error) { diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index e3291ec8c..5b0e64c79 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -213,16 +213,22 @@ func HandleCallback(c echo.Context) error { log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) return handler.HandleHTTPError(err, c) } - // check if we have seen these teams before. - // find or create Teams and assign user as teammember. + + //TODO: fix this error check + // nil is no problem + if len(teamData) > 0 { + //find old teams for user through oidc + oldOidcTeams, _ := models.FindAllOidcTeamIDsForUser(s, u.ID) + // check if we have seen these teams before. + // find or create Teams and assign user as teammember. + var oidcTeams []int64 log.Debugf("TeamData is set %v", teamData) teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u) if err != nil { log.Errorf("Error verifying team for name %v, got %v", cl.Name, teams, err) return err } - for _, team := range teams { tm := models.TeamMember{TeamID: team.ID, Username: u.Username} exists, err := tm.CheckMembership(s) @@ -234,9 +240,10 @@ func HandleCallback(c echo.Context) error { } else { log.Debugf("Team exists? %v or error: %v", exists, err) } + oidcTeams = append(oidcTeams, team.ID) } + SignOutFromOrDeleteTeamsByID(s, u, notIn(oldOidcTeams, oidcTeams)) } - err = s.Commit() if err != nil { _ = s.Rollback() @@ -247,13 +254,30 @@ func HandleCallback(c echo.Context) error { return auth.NewUserAuthTokenResponse(u, c, false) } +func SignOutFromOrDeleteTeamsByID(s *xorm.Session, u *user.User, teamIDs []int64) { + for _, teamID := range teamIDs { + tm := models.TeamMember{TeamID: teamID, Username: u.Username} + err := tm.Delete(s, u) + if err != nil { + team, err := models.GetTeamByID(s, teamID) + if err != nil { + log.Errorf("Cannot find team with id: %v, err: %v", teamID, err) + } else { + err = team.Delete(s, u) + if err != nil { + log.Errorf("Cannot delete team %v", err) + } + } + } + } +} + func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []TeamData, err error) { teamData = []TeamData{} if groups != nil { el := groups.([]interface{}) for _, data := range el { team := data.(map[string]interface{}) - log.Debugf("%s", team) var name string var description string var oidcID string @@ -394,3 +418,23 @@ func getOrCreateUser(s *xorm.Session, cl *claims, issuer, subject string) (u *us return } + +// find the elements which appear in slice1,but not in slice2 +func notIn(slice1 []int64, slice2 []int64) []int64 { + var diff []int64 + + for _, s1 := range slice1 { + found := false + for _, s2 := range slice2 { + if s1 == s2 { + found = true + break + } + } + // String not found. We add it to return slice + if !found { + diff = append(diff, s1) + } + } + return diff +} -- 2.45.1 From 381a2bc3aabd0d9e906b97b772e4dc153c0f75a6 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 1 Feb 2023 16:34:35 +0100 Subject: [PATCH 13/93] make provider scopes more robust add default openid profile email --- pkg/modules/auth/openid/providers.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/modules/auth/openid/providers.go b/pkg/modules/auth/openid/providers.go index f045d19d3..5e14c1b31 100644 --- a/pkg/modules/auth/openid/providers.go +++ b/pkg/modules/auth/openid/providers.go @@ -125,6 +125,10 @@ func getProviderFromMap(pi map[string]interface{}) (provider *Provider, err erro logoutURL = "" } + scope, _ := pi["scope"].(string) + if scope == "" { + scope = "openid profile email" + } provider = &Provider{ Name: pi["name"].(string), Key: k, @@ -132,7 +136,7 @@ func getProviderFromMap(pi map[string]interface{}) (provider *Provider, err erro OriginalAuthURL: pi["authurl"].(string), ClientSecret: pi["clientsecret"].(string), LogoutURL: logoutURL, - Scope: pi["scope"].(string), + Scope: scope, } cl, is := pi["clientid"].(int) -- 2.45.1 From 5942d78d8aba1c4b03681c53f5a006f7d81338f3 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 1 Feb 2023 16:35:12 +0100 Subject: [PATCH 14/93] remove user from all oidc teams if token is empty --- pkg/modules/auth/openid/openid.go | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 5b0e64c79..f11f3fddd 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -214,15 +214,12 @@ func HandleCallback(c echo.Context) error { return handler.HandleHTTPError(err, c) } - //TODO: fix this error check - // nil is no problem - + //find old teams for user through oidc + oldOidcTeams, _ := models.FindAllOidcTeamIDsForUser(s, u.ID) + var oidcTeams []int64 if len(teamData) > 0 { - //find old teams for user through oidc - oldOidcTeams, _ := models.FindAllOidcTeamIDsForUser(s, u.ID) // check if we have seen these teams before. // find or create Teams and assign user as teammember. - var oidcTeams []int64 log.Debugf("TeamData is set %v", teamData) teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u) if err != nil { @@ -242,8 +239,8 @@ func HandleCallback(c echo.Context) error { } oidcTeams = append(oidcTeams, team.ID) } - SignOutFromOrDeleteTeamsByID(s, u, notIn(oldOidcTeams, oidcTeams)) } + SignOutFromOrDeleteTeamsByID(s, u, notIn(oldOidcTeams, oidcTeams)) err = s.Commit() if err != nil { _ = s.Rollback() @@ -345,12 +342,6 @@ func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []TeamData, u *use return te, err } -// assign user to team -// remove user from team if not in group -// if multiple teams found with same name -> do nothing -// optional: assign by id -// - func getOrCreateUser(s *xorm.Session, cl *claims, issuer, subject string) (u *user.User, err error) { // Check if the user exists for that issuer and subject -- 2.45.1 From 1ea033e0d236dc518b8235c99d20b9238e19077f Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 1 Feb 2023 16:35:27 +0100 Subject: [PATCH 15/93] add config.yml.sample for seting up vikunja_scope and group assignment feature --- config.yml.sample | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config.yml.sample b/config.yml.sample index 88465a03d..667cb8bb3 100644 --- a/config.yml.sample +++ b/config.yml.sample @@ -325,6 +325,10 @@ auth: clientid: # The client secret used to authenticate Vikunja at the OpenID Connect provider. clientsecret: + # The scope necessary to use oidc. + # If you want to use the Feature to create and assign to vikunja teams via oidc, you have to add the custom "vikunja_scope". + # e.g. scope: openid email profile vikunja_scope + scope: openid email profile # Prometheus metrics endpoint metrics: -- 2.45.1 From 01ff27f25f3fe4f46cfa08d922b458bfd9ea9046 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 1 Feb 2023 16:36:01 +0100 Subject: [PATCH 16/93] add openid.md as readme for feature: 950 assigning group through oidc claim --- pkg/modules/auth/openid/openid.md | 99 +++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 pkg/modules/auth/openid/openid.md diff --git a/pkg/modules/auth/openid/openid.md b/pkg/modules/auth/openid/openid.md new file mode 100644 index 000000000..c3db48822 --- /dev/null +++ b/pkg/modules/auth/openid/openid.md @@ -0,0 +1,99 @@ +regarding: +https://kolaente.dev/vikunja/api/pulls/1279 + +# Assign teams via oidc +This PR adds the functionality to assign users to teams via oidc. +Read carefully and brief your administrators to use this feature. +Tested with oidc provider authentik. +To distinguish between groups created in vikunja and groups generated via oidc, there is an attribute neccessary, which is called: *oidcID* + +## Setup +Edit config.yml to include scope: openid profile email vikunja_scope + +For authentik to use group assignment feature: +- go to: .../if/admin/#/core/property-mappings + +- create a new mapping called "vikunja_scope" + +There is a field to enter python expressions that will be delivered with the oidc token. + +- write a small script, for adding group information to vikunja_scope. + + +```python +groupsDict = {"vikunja_groups": []} +for group in request.user.ak_groups.all(): + groupsDict["vikunja_groups"].append({"name": group.name, "oidcID": group.num_pk}) +return groupsDict + +""" +output example: +{ + "vikunja_groups": [ + { + "name": "team 1", + "oidcID": 33349 + }, + { + "name": "team 2", + "oidcID": 35933 + } + ] +} +""" +``` + +Now when you log in via oidc there will be a list of scopes you are claiming from your oidc provider. +You should see "the description you entered in the oidc provider's admin area" + +- Log in and go to teams. +- You will see "(sso: XXXXX)" written next to each team you were asigned through oidc. + + +## IMPORTANT NOTES: +**SSO/OIDC teams cannot be edited.** + +**It is crucial to call the element "vikunja_groups" since this is the name vikunja is looking for.** + +**Additionally, make sure to deliver an "oidcID" and a "name".** + + + + +____________________________________________________________________________ + +## BEHAVIOR + +*(.. examples for "team1" ..)* + +1. *Token delivers team.name +team.oidcId and Vikunja team does not exist:* \ +New team will be created called "team 1" with attribute oidcId: "33929" + + +2. *In Vikunja Team with name "team 1" already exists in vikunja, but has no oidcID set:* \ +new team will be created called "team 1" with attribute oidcId: "33929" + + +3. *In Vikunja Team with name "team 1" already exists in vikunja, but has different oidcID set:* \ +new team will be created called "team 1" with attribute oidcId: "33929" + + +4. *In Vikunja Team with oidcID "33929" already exists in vikunja, but has different name than "team1":* \ +new team will be created called "team 1" with attribute oidcId: "33929" + + +5. *Scope vikunja_scope is not set:* \ +nothing happens + + +6. *oidcID is not set:* \ +You'll get error. +Custom Scope malformed +"The custom scope set by the OIDC provider is malformed. Please make sure the openid provider sets the data correctly for your scope. Check especially to have set an oidcID." + +7. *In Vikunja I am in "team 3" with oidcID "", but the token does not deliver any data for "team 3":* \ +You will stay in team 3 since it was not set by the oidc provider + +8. *In Vikunja I am in "team 3" with oidcID "12345", but the token does not deliver any data for "team 3"*:\ +You will be signed out of all teams, which have an oidcID set and are not contained in the token. +Especially if you've been the last team member, the team will be deleted. \ No newline at end of file -- 2.45.1 From 99c987efc02fceed9331eb2ec221d83e71d2d161 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 16:14:03 +0100 Subject: [PATCH 17/93] add errors to error doc, rewrite error messages specify error on teams model, add more declarative error specify error message on ErrOIDCTeamDoesNotExist --- docs/content/doc/usage/errors.md | 5 ++++ pkg/models/error.go | 40 +++++++++++++++++++++++++------- pkg/models/teams.go | 2 +- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/docs/content/doc/usage/errors.md b/docs/content/doc/usage/errors.md index f3a6c8e4f..5f8d9f098 100644 --- a/docs/content/doc/usage/errors.md +++ b/docs/content/doc/usage/errors.md @@ -106,6 +106,11 @@ This document describes the different errors Vikunja can return. | 6005 | 409 | The user is already a member of that team. | | 6006 | 400 | Cannot delete the last team member. | | 6007 | 403 | The team does not have access to the project to perform that action. | +| 6008 | 400 | There are no teams found with that team name | +| 6009 | 400 | There is no oidc team with that team name and oidcId | +| 6010 | 400 | There are no oidc teams found for the user | + + ## User Project Access diff --git a/pkg/models/error.go b/pkg/models/error.go index 4cf44d8c8..10fc053f5 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1181,22 +1181,46 @@ type ErrTeamsDoNotExist struct { Name string } -// IsErrTeamDoNotExist checks if an error is ErrTeamDoesNotExist. +// IsErrTeamsDoNotExist checks if an error is ErrTeamsDoNotExist. func IsErrTeamsDoNotExist(err error) bool { _, ok := err.(ErrTeamsDoNotExist) return ok } func (err ErrTeamsDoNotExist) Error() string { - return fmt.Sprintf("Team does not exist [Team Name: %v]", err.Name) + return fmt.Sprintf("No teams with that name exist [Team Name: %v]", err.Name) } -// ErrCodeTeamDoesNotExist holds the unique world-error code of this error +// ErrCodeTeamsDoesNotExist holds the unique world-error code of this error const ErrCodeTeamsDoNotExist = 6008 // HTTPError holds the http error description func (err ErrTeamsDoNotExist) HTTPError() web.HTTPError { - return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No team with given name exists."} + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No teams with that name exist"} +} + +// ErrOIDCTeamDoesNotExist represents an error where a team with specified name and specified oidcId property does not exist +type ErrOIDCTeamDoesNotExist struct { + OidcId string + Name string +} + +// IsErrOIDCTeamDoesNotExist checks if an error is ErrOIDCTeamDoesNotExist. +func IsErrOIDCTeamDoesNotExist(err error) bool { + _, ok := err.(ErrOIDCTeamDoesNotExist) + return ok +} + +func (err ErrOIDCTeamDoesNotExist) Error() string { + return fmt.Sprintf("No Team with that name and valid property oidcId could be found [Team Name: %v] [OidcId : %v] ", err.Name, err.OidcId) +} + +// ErrCodeTeamDoesNotExist holds the unique world-error code of this error +const ErrCodeOIDCTeamDoesNotExist = 6009 + +// HTTPError holds the http error description +func (err ErrOIDCTeamDoesNotExist) HTTPError() web.HTTPError { + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Team with that name and valid property oidcId could be found."} } // ErrOIDCTeamsDoNotExistForUser represents an error where an oidcTeam does not exist for the user @@ -1206,20 +1230,20 @@ type ErrOIDCTeamsDoNotExistForUser struct { // IsErrOIDCTeamsDoNotExistForUser checks if an error is ErrOIDCTeamsDoNotExistForUser. func IsErrOIDCTeamsDoNotExistForUser(err error) bool { - _, ok := err.(ErrTeamDoesNotExist) + _, ok := err.(ErrOIDCTeamsDoNotExistForUser) return ok } func (err ErrOIDCTeamsDoNotExistForUser) Error() string { - return fmt.Sprintf("No Oidc exists for User [User ID: %d]", err.UserID) + return fmt.Sprintf("No Teams with property oidcId could be found for User [User ID: %d]", err.UserID) } // ErrCodeTeamDoesNotExist holds the unique world-error code of this error -const ErrCodeOIDCTeamsDoNotExistForUser = 6009 +const ErrCodeOIDCTeamsDoNotExistForUser = 6010 // HTTPError holds the http error description func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError { - return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "This team does not exist."} + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Teams with property oidcId could be found for User."} } // ==================== diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 7aeccd03a..a18af0d31 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -158,7 +158,7 @@ func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (te if exists && err == nil { return team, nil } - return team, ErrTeamsDoNotExist{oidcID} + return team, ErrOIDCTeamDoesNotExist{teamName, oidcID} } func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err error) { -- 2.45.1 From 765cfae63ab1ceb5b4f714f6ce52f729bf355fbc Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 17:05:34 +0100 Subject: [PATCH 18/93] rewok checkMembership to not load user and improvements on return val --- pkg/models/team_members.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index 933545336..b61cdb045 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -110,18 +110,13 @@ func (tm *TeamMember) Delete(s *xorm.Session, _ web.Auth) (err error) { } func (tm *TeamMember) CheckMembership(s *xorm.Session) (exists bool, err error) { - member, err := user2.GetUserByUsername(s, tm.Username) - if err != nil { - return - } - tm.UserID = member.ID exists, err = s. Where("team_id = ? AND user_id = ?", tm.TeamID, tm.UserID). Get(&TeamMember{}) - if exists { + if exists && err == nil { return } - return exists, ErrUserIsMemberOfTeam{tm.UserID, tm.UserID} + return exists, err } // Update toggles a team member's admin status -- 2.45.1 From a7c1fb919c67f50b22304c9cccb54f889a774e69 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 17:24:42 +0100 Subject: [PATCH 19/93] remove manage admin function, nullcheck for oidc_id, undo removal of * in method TableName --- pkg/models/teams.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/pkg/models/teams.go b/pkg/models/teams.go index a18af0d31..0e30971cc 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -82,7 +82,7 @@ type TeamMember struct { } // TableName makes beautiful table names -func (TeamMember) TableName() string { +func (*TeamMember) TableName() string { return "team_members" } @@ -94,6 +94,7 @@ type TeamUser struct { TeamID int64 `json:"-"` } +// TeamData is the relevant data for a team and is delivered by oidc token type TeamData struct { TeamName string OidcID string @@ -166,7 +167,7 @@ func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err e Table("team_members"). Where("user_id = ? ", userID). Join("RIGHT", "teams", "teams.id = team_members.team_id"). - Where("teams.oidc_id != ?", ""). + Where("teams.oidc_id != ? AND teams.oidc_id IS NOT NULL", ""). Cols("teams.id"). Find(&ts) if ts == nil || err != nil { @@ -325,8 +326,7 @@ func (t *Team) Create(s *xorm.Session, a web.Auth) (err error) { return } - var admin = true - tm := TeamMember{TeamID: t.ID, Username: doer.Username, Admin: admin} + tm := TeamMember{TeamID: t.ID, Username: doer.Username, Admin: true} if err = tm.Create(s, doer); err != nil { return err } @@ -337,11 +337,6 @@ func (t *Team) Create(s *xorm.Session, a web.Auth) (err error) { }) } -func (t *Team) ManageAdminRight(teamMember TeamMember, admin bool) { - // Insert the current user as member and admin - teamMember.Admin = admin -} - // Delete deletes a team // @Summary Deletes a team // @Description Delets a team. This will also remove the access for all users in that team. -- 2.45.1 From 7774cc5823499d53664ec60da044b3f45fe9e5c6 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 17:26:22 +0100 Subject: [PATCH 20/93] use models.TeamData instead of declaring struct twice --- pkg/modules/auth/openid/openid.go | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index f11f3fddd..d9fb8467a 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -58,11 +58,6 @@ type Provider struct { openIDProvider *oidc.Provider Oauth2Config *oauth2.Config `json:"-"` } -type TeamData struct { - TeamName string - OidcID string - Description string -} type claims struct { Email string `json:"email"` Name string `json:"name"` @@ -269,8 +264,8 @@ func SignOutFromOrDeleteTeamsByID(s *xorm.Session, u *user.User, teamIDs []int64 } } -func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []TeamData, err error) { - teamData = []TeamData{} +func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []models.TeamData, err error) { + teamData = []models.TeamData{} if groups != nil { el := groups.([]interface{}) for _, data := range el { @@ -301,13 +296,13 @@ func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []Te log.Errorf("Claim of your custom scope does not hold name or oidcID for automatic group assignment through oidc provider. Please check %s", provider.Name) return teamData, &user.ErrOpenIDCustomScopeMalformed{} } - teamData = append(teamData, TeamData{TeamName: name, OidcID: oidcID, Description: description}) + teamData = append(teamData, models.TeamData{TeamName: name, OidcID: oidcID, Description: description}) } } return teamData, nil } -func CreateTeamWithData(s *xorm.Session, teamData TeamData, u *user.User) (team *models.Team, err error) { +func CreateTeamWithData(s *xorm.Session, teamData models.TeamData, u *user.User) (team *models.Team, err error) { tea := &models.Team{ Name: teamData.TeamName, Description: teamData.Description, @@ -320,7 +315,7 @@ func CreateTeamWithData(s *xorm.Session, teamData TeamData, u *user.User) (team } // this functions creates an array of existing teams that was generated from the oidc data. -func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []TeamData, u *user.User) (te []models.Team, err error) { +func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.TeamData, u *user.User) (te []models.Team, err error) { te = []models.Team{} // Procedure can only be successful if oidcID is set and converted to string for _, oidcTeam := range teamData { -- 2.45.1 From 0f04ac2519ea34529aebb81b01c8e456b5c949a7 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 18:48:28 +0100 Subject: [PATCH 21/93] move find x not in y for int64 slices to utils --- pkg/utils/slice_difference.go | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 pkg/utils/slice_difference.go diff --git a/pkg/utils/slice_difference.go b/pkg/utils/slice_difference.go new file mode 100644 index 000000000..cc01fad10 --- /dev/null +++ b/pkg/utils/slice_difference.go @@ -0,0 +1,37 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-2021 Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public Licensee as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public Licensee for more details. +// +// You should have received a copy of the GNU Affero General Public Licensee +// along with this program. If not, see . + +package utils + +// find the elements which appear in slice1,but not in slice2 +func NotIn(slice1 []int64, slice2 []int64) []int64 { + var diff []int64 + + for _, s1 := range slice1 { + found := false + for _, s2 := range slice2 { + if s1 == s2 { + found = true + break + } + } + // int64 not found. We add it to return slice + if !found { + diff = append(diff, s1) + } + } + return diff +} -- 2.45.1 From 3c51966b08babdf785e1d61ede314eb17cfcfe04 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 19:52:18 +0100 Subject: [PATCH 22/93] rework openid.go, add errors to return, make team deletion more robust --- pkg/models/team_members.go | 13 +++-- pkg/modules/auth/openid/openid.go | 96 ++++++++++++++----------------- 2 files changed, 52 insertions(+), 57 deletions(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index b61cdb045..da02e4f2e 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -44,7 +44,6 @@ func (tm *TeamMember) Create(s *xorm.Session, a web.Auth) (err error) { if err != nil { return err } - // Check if the user exists member, err := user2.GetUserByUsername(s, tm.Username) if err != nil { @@ -113,12 +112,18 @@ func (tm *TeamMember) CheckMembership(s *xorm.Session) (exists bool, err error) exists, err = s. Where("team_id = ? AND user_id = ?", tm.TeamID, tm.UserID). Get(&TeamMember{}) - if exists && err == nil { - return - } return exists, err } +func (tm *TeamMember) GetMemberCount(s *xorm.Session) (memberCount int, err error) { + members := []TeamMember{} + err = s. + Where("team_id = ?", tm.TeamID). + Cols("user_id"). + Find(&members) + return len(members), err +} + // Update toggles a team member's admin status // @Summary Toggle a team member's admin status // @Description If a user is team admin, this will make them member and vise-versa. diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index d9fb8467a..a1610dc65 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -21,21 +21,22 @@ import ( "encoding/json" "errors" "net/http" + "strconv" "strings" "code.vikunja.io/web/handler" "code.vikunja.io/api/pkg/db" - "xorm.io/xorm" - "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/models" "code.vikunja.io/api/pkg/modules/auth" "code.vikunja.io/api/pkg/user" + "code.vikunja.io/api/pkg/utils" "github.com/coreos/go-oidc/v3/oidc" petname "github.com/dustinkirkland/golang-petname" "github.com/labstack/echo/v4" "golang.org/x/oauth2" + "xorm.io/xorm" ) // Callback contains the callback after an auth request was made and redirected @@ -63,7 +64,6 @@ type claims struct { Name string `json:"name"` PreferredUsername string `json:"preferred_username"` Nickname string `json:"nickname"` - Teams []string `json:"groups"` VikunjaGroups interface{} `json:"vikunja_groups"` } @@ -195,7 +195,6 @@ func HandleCallback(c echo.Context) error { // Check if we have seen this user before u, err := getOrCreateUser(s, cl, idToken.Issuer, idToken.Subject) - if err != nil { _ = s.Rollback() log.Errorf("Error creating new user for provider %s: %v", provider.Name, err) @@ -203,14 +202,18 @@ func HandleCallback(c echo.Context) error { } // does the oidc token contain well formed "vikunja_groups" through vikunja_scope - teamData, err := getTeamDataFromToken(cl.VikunjaGroups, provider) - if err != nil { - log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) - return handler.HandleHTTPError(err, c) + teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, provider) + if len(errs) > 0 { + for _, err := range errs { + log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) + } } //find old teams for user through oidc - oldOidcTeams, _ := models.FindAllOidcTeamIDsForUser(s, u.ID) + oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) + if err != nil { + log.Errorf("No Oidc Teams found for user", err) + } var oidcTeams []int64 if len(teamData) > 0 { // check if we have seen these teams before. @@ -222,20 +225,21 @@ func HandleCallback(c echo.Context) error { return err } for _, team := range teams { - tm := models.TeamMember{TeamID: team.ID, Username: u.Username} + tm := models.TeamMember{TeamID: team.ID, UserID: u.ID, Username: u.Username} exists, err := tm.CheckMembership(s) if !exists { err = tm.Create(s, u) if err != nil { - log.Debugf("Could not assign %v to %v. %v", u.Username, team.Name, err) + log.Errorf("Could not assign %v to %v. %v", u.Username, team.Name, err) } - } else { - log.Debugf("Team exists? %v or error: %v", exists, err) } oidcTeams = append(oidcTeams, team.ID) } } - SignOutFromOrDeleteTeamsByID(s, u, notIn(oldOidcTeams, oidcTeams)) + errs = SignOutFromOrDeleteTeamsByID(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + for _, err := range errs { + log.Errorf("Found Error while signing out from teams %v", err) + } err = s.Commit() if err != nil { _ = s.Rollback() @@ -246,26 +250,35 @@ func HandleCallback(c echo.Context) error { return auth.NewUserAuthTokenResponse(u, c, false) } -func SignOutFromOrDeleteTeamsByID(s *xorm.Session, u *user.User, teamIDs []int64) { +func SignOutFromOrDeleteTeamsByID(s *xorm.Session, u *user.User, teamIDs []int64) (errs []error) { + errs = []error{} for _, teamID := range teamIDs { - tm := models.TeamMember{TeamID: teamID, Username: u.Username} - err := tm.Delete(s, u) - if err != nil { + tm := models.TeamMember{TeamID: teamID, UserID: u.ID, Username: u.Username} + exists, err := tm.CheckMembership(s) + memberCount, _ := tm.GetMemberCount(s) + if !exists { + continue + } + err = tm.Delete(s, u) + // if you cannot delete the team_member + if err != nil || memberCount <= 1 { team, err := models.GetTeamByID(s, teamID) if err != nil { - log.Errorf("Cannot find team with id: %v, err: %v", teamID, err) - } else { - err = team.Delete(s, u) - if err != nil { - log.Errorf("Cannot delete team %v", err) - } + errs = append(errs, err) + continue + } + err = team.Delete(s, u) + if err != nil { + errs = append(errs, err) } } } + return errs } -func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []models.TeamData, err error) { +func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []models.TeamData, errs []error) { teamData = []models.TeamData{} + errs = []error{} if groups != nil { el := groups.([]interface{}) for _, data := range el { @@ -282,24 +295,24 @@ func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []mo if team["oidcID"] != nil { switch t := team["oidcID"].(type) { case int64: - oidcID = fmt.Sprintf("%v", team["oidcID"]) + oidcID = strconv.FormatInt(team["oidcID"].(int64), 10) case string: oidcID = string(team["oidcID"].(string)) case float64: - fl := float64(team["oidcID"].(float64)) - oidcID = fmt.Sprintf("%v", fl) + oidcID = strconv.FormatFloat(team["oidcID"].(float64), 'f', -1, 64) default: log.Errorf("No oidcID assigned for %v or type %v not supported", team, t) } } if name == "" || oidcID == "" { log.Errorf("Claim of your custom scope does not hold name or oidcID for automatic group assignment through oidc provider. Please check %s", provider.Name) - return teamData, &user.ErrOpenIDCustomScopeMalformed{} + errs = append(errs, &user.ErrOpenIDCustomScopeMalformed{}) + continue } teamData = append(teamData, models.TeamData{TeamName: name, OidcID: oidcID, Description: description}) } } - return teamData, nil + return teamData, errs } func CreateTeamWithData(s *xorm.Session, teamData models.TeamData, u *user.User) (team *models.Team, err error) { @@ -308,8 +321,6 @@ func CreateTeamWithData(s *xorm.Session, teamData models.TeamData, u *user.User) Description: teamData.Description, OidcID: teamData.OidcID, } - log.Debugf("Teams: %v", tea.OidcID) - err = tea.Create(s, u) return tea, err } @@ -333,7 +344,6 @@ func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.TeamData, } } - log.Debugf("Array: %v", te) return te, err } @@ -404,23 +414,3 @@ func getOrCreateUser(s *xorm.Session, cl *claims, issuer, subject string) (u *us return } - -// find the elements which appear in slice1,but not in slice2 -func notIn(slice1 []int64, slice2 []int64) []int64 { - var diff []int64 - - for _, s1 := range slice1 { - found := false - for _, s2 := range slice2 { - if s1 == s2 { - found = true - break - } - } - // String not found. We add it to return slice - if !found { - diff = append(diff, s1) - } - } - return diff -} -- 2.45.1 From ef854b1871f2699abe62bc7ab0f6eb18ccedd72e Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 20:04:25 +0100 Subject: [PATCH 23/93] make documentation cleaner --- config.yml.sample | 2 +- pkg/modules/auth/openid/openid.md | 15 ++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/config.yml.sample b/config.yml.sample index 667cb8bb3..fbef4b629 100644 --- a/config.yml.sample +++ b/config.yml.sample @@ -326,7 +326,7 @@ auth: # The client secret used to authenticate Vikunja at the OpenID Connect provider. clientsecret: # The scope necessary to use oidc. - # If you want to use the Feature to create and assign to vikunja teams via oidc, you have to add the custom "vikunja_scope". + # If you want to use the Feature to create and assign to vikunja teams via oidc, you have to add the custom "vikunja_scope" and check [openid.md](https://kolaente.dev/vikunja/api/src/branch/main/pkg/modules/auth/openid/openid.md) # e.g. scope: openid email profile vikunja_scope scope: openid email profile diff --git a/pkg/modules/auth/openid/openid.md b/pkg/modules/auth/openid/openid.md index c3db48822..c63a89c22 100644 --- a/pkg/modules/auth/openid/openid.md +++ b/pkg/modules/auth/openid/openid.md @@ -1,14 +1,12 @@ -regarding: -https://kolaente.dev/vikunja/api/pulls/1279 - # Assign teams via oidc This PR adds the functionality to assign users to teams via oidc. Read carefully and brief your administrators to use this feature. Tested with oidc provider authentik. -To distinguish between groups created in vikunja and groups generated via oidc, there is an attribute neccessary, which is called: *oidcID* +To distinguish between teams created in vikunja and teams generated via oidc, an attribute for vikunja teams is introduced, which is called: *oidcID* ## Setup -Edit config.yml to include scope: openid profile email vikunja_scope + +Edit [config.yml](https://kolaente.dev/vikunja/api/src/branch/main/config.yml.sample) to include scope: openid profile email vikunja_scope For authentik to use group assignment feature: - go to: .../if/admin/#/core/property-mappings @@ -51,12 +49,11 @@ You should see "the description you entered in the oidc provider's admin area" ## IMPORTANT NOTES: -**SSO/OIDC teams cannot be edited.** +* **SSO/OIDC teams cannot be edited.** -**It is crucial to call the element "vikunja_groups" since this is the name vikunja is looking for.** - -**Additionally, make sure to deliver an "oidcID" and a "name".** +* **It is crucial to call the element "vikunja_groups" since this is the name vikunja is looking for.** +* **Additionally, make sure to deliver an "oidcID" and a "name".** -- 2.45.1 From 8c65f632fb9a0e8edb4404e0d7065bd945926bea Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 20:43:24 +0100 Subject: [PATCH 24/93] fix lint --- pkg/models/error.go | 4 +-- pkg/modules/auth/openid/openid.go | 60 ++++++++++++++++--------------- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/pkg/models/error.go b/pkg/models/error.go index 10fc053f5..34fa50422 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1201,7 +1201,7 @@ func (err ErrTeamsDoNotExist) HTTPError() web.HTTPError { // ErrOIDCTeamDoesNotExist represents an error where a team with specified name and specified oidcId property does not exist type ErrOIDCTeamDoesNotExist struct { - OidcId string + OidcID string Name string } @@ -1212,7 +1212,7 @@ func IsErrOIDCTeamDoesNotExist(err error) bool { } func (err ErrOIDCTeamDoesNotExist) Error() string { - return fmt.Sprintf("No Team with that name and valid property oidcId could be found [Team Name: %v] [OidcId : %v] ", err.Name, err.OidcId) + return fmt.Sprintf("No Team with that name and valid property oidcId could be found [Team Name: %v] [OidcId : %v] ", err.Name, err.OidcID) } // ErrCodeTeamDoesNotExist holds the unique world-error code of this error diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index a1610dc65..44b761545 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -203,38 +203,18 @@ func HandleCallback(c echo.Context) error { // does the oidc token contain well formed "vikunja_groups" through vikunja_scope teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, provider) - if len(errs) > 0 { - for _, err := range errs { - log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) - } + for _, err := range errs { + log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) } //find old teams for user through oidc oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) if err != nil { - log.Errorf("No Oidc Teams found for user", err) + log.Errorf("No Oidc Teams found for user %v", err) } - var oidcTeams []int64 - if len(teamData) > 0 { - // check if we have seen these teams before. - // find or create Teams and assign user as teammember. - log.Debugf("TeamData is set %v", teamData) - teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u) - if err != nil { - log.Errorf("Error verifying team for name %v, got %v", cl.Name, teams, err) - return err - } - for _, team := range teams { - tm := models.TeamMember{TeamID: team.ID, UserID: u.ID, Username: u.Username} - exists, err := tm.CheckMembership(s) - if !exists { - err = tm.Create(s, u) - if err != nil { - log.Errorf("Could not assign %v to %v. %v", u.Username, team.Name, err) - } - } - oidcTeams = append(oidcTeams, team.ID) - } + oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) + if err != nil { + log.Errorf("Could not proceed with group routine %v", err) } errs = SignOutFromOrDeleteTeamsByID(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) for _, err := range errs { @@ -250,16 +230,40 @@ func HandleCallback(c echo.Context) error { return auth.NewUserAuthTokenResponse(u, c, false) } +func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.TeamData) (oidcTeams []int64, err error) { + if len(teamData) > 0 { + // check if we have seen these teams before. + // find or create Teams and assign user as teammember. + teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u) + if err != nil { + log.Errorf("Error verifying team for %v, got %v. Error: %v", u.Name, teams, err) + return nil, err + } + for _, team := range teams { + tm := models.TeamMember{TeamID: team.ID, UserID: u.ID, Username: u.Username} + exists, _ := tm.CheckMembership(s) + if !exists { + err = tm.Create(s, u) + if err != nil { + log.Errorf("Could not assign %v to %v. %v", u.Username, team.Name, err) + } + } + oidcTeams = append(oidcTeams, team.ID) + } + } + return oidcTeams, err + +} func SignOutFromOrDeleteTeamsByID(s *xorm.Session, u *user.User, teamIDs []int64) (errs []error) { errs = []error{} for _, teamID := range teamIDs { tm := models.TeamMember{TeamID: teamID, UserID: u.ID, Username: u.Username} - exists, err := tm.CheckMembership(s) + exists, _ := tm.CheckMembership(s) memberCount, _ := tm.GetMemberCount(s) if !exists { continue } - err = tm.Delete(s, u) + err := tm.Delete(s, u) // if you cannot delete the team_member if err != nil || memberCount <= 1 { team, err := models.GetTeamByID(s, teamID) -- 2.45.1 From 3a75aa99fe74f251f65f447577b518d73e5bc62a Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 23 Feb 2023 15:23:32 +0100 Subject: [PATCH 25/93] undo team gets deleted if user is last team member remove logic behind deleting last team_member --- pkg/models/team_members.go | 10 +++++----- pkg/modules/auth/openid/openid.go | 27 ++++++++++++--------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index da02e4f2e..ed7cded48 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -115,13 +115,13 @@ func (tm *TeamMember) CheckMembership(s *xorm.Session) (exists bool, err error) return exists, err } -func (tm *TeamMember) GetMemberCount(s *xorm.Session) (memberCount int, err error) { - members := []TeamMember{} - err = s. +func (tm *TeamMember) GetMemberCount(s *xorm.Session) (memberCount int64, err error) { + member := TeamMember{} + memberCount, err = s. Where("team_id = ?", tm.TeamID). Cols("user_id"). - Find(&members) - return len(members), err + Count(&member) + return memberCount, err } // Update toggles a team member's admin status diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 44b761545..876c703f5 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -216,7 +216,8 @@ func HandleCallback(c echo.Context) error { if err != nil { log.Errorf("Could not proceed with group routine %v", err) } - errs = SignOutFromOrDeleteTeamsByID(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + errs = SignOutFromTeamsByID(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + log.Errorf("%v", errs) for _, err := range errs { log.Errorf("Found Error while signing out from teams %v", err) } @@ -254,27 +255,23 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models. return oidcTeams, err } -func SignOutFromOrDeleteTeamsByID(s *xorm.Session, u *user.User, teamIDs []int64) (errs []error) { +func SignOutFromTeamsByID(s *xorm.Session, u *user.User, teamIDs []int64) (errs []error) { errs = []error{} for _, teamID := range teamIDs { tm := models.TeamMember{TeamID: teamID, UserID: u.ID, Username: u.Username} - exists, _ := tm.CheckMembership(s) - memberCount, _ := tm.GetMemberCount(s) + exists, err := tm.CheckMembership(s) + if err != nil { + errs = append(errs, err) + continue + } if !exists { continue } - err := tm.Delete(s, u) + err = tm.Delete(s, u) // if you cannot delete the team_member - if err != nil || memberCount <= 1 { - team, err := models.GetTeamByID(s, teamID) - if err != nil { - errs = append(errs, err) - continue - } - err = team.Delete(s, u) - if err != nil { - errs = append(errs, err) - } + if err != nil { + errs = append(errs, err) + continue } } return errs -- 2.45.1 From 9dd3317908040deb2aefc008808f285462dbbf75 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 23 Feb 2023 15:48:38 +0100 Subject: [PATCH 26/93] change get to exist in team_members.go:114 --- pkg/models/team_members.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index ed7cded48..edc9632df 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -111,7 +111,7 @@ func (tm *TeamMember) Delete(s *xorm.Session, _ web.Auth) (err error) { func (tm *TeamMember) CheckMembership(s *xorm.Session) (exists bool, err error) { exists, err = s. Where("team_id = ? AND user_id = ?", tm.TeamID, tm.UserID). - Get(&TeamMember{}) + Exist(&TeamMember{}) return exists, err } -- 2.45.1 From 50a5825bcec88d5d6349c544eaf2dee2fe7ee592 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 23 Feb 2023 15:52:16 +0100 Subject: [PATCH 27/93] add punctuation and comments for errors --- docs/content/doc/usage/errors.md | 6 +++--- pkg/models/error.go | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/content/doc/usage/errors.md b/docs/content/doc/usage/errors.md index 5f8d9f098..605cdf364 100644 --- a/docs/content/doc/usage/errors.md +++ b/docs/content/doc/usage/errors.md @@ -106,9 +106,9 @@ This document describes the different errors Vikunja can return. | 6005 | 409 | The user is already a member of that team. | | 6006 | 400 | Cannot delete the last team member. | | 6007 | 403 | The team does not have access to the project to perform that action. | -| 6008 | 400 | There are no teams found with that team name | -| 6009 | 400 | There is no oidc team with that team name and oidcId | -| 6010 | 400 | There are no oidc teams found for the user | +| 6008 | 400 | There are no teams found with that team name. | +| 6009 | 400 | There is no oidc team with that team name and oidcId. | +| 6010 | 400 | There are no oidc teams found for the user. | diff --git a/pkg/models/error.go b/pkg/models/error.go index 34fa50422..2b6772ff7 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1177,6 +1177,7 @@ func (err ErrTeamDoesNotHaveAccessToProject) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusForbidden, Code: ErrCodeTeamDoesNotHaveAccessToProject, Message: "This team does not have access to the project."} } +// ErrTeamsDoNotExist represents an error where Teams searched via non-unique name do not exist. type ErrTeamsDoNotExist struct { Name string } @@ -1211,6 +1212,7 @@ func IsErrOIDCTeamDoesNotExist(err error) bool { return ok } +// ErrTeamDoesNotExist represents an error where a team does not exist func (err ErrOIDCTeamDoesNotExist) Error() string { return fmt.Sprintf("No Team with that name and valid property oidcId could be found [Team Name: %v] [OidcId : %v] ", err.Name, err.OidcID) } -- 2.45.1 From c3a1a5062a556ef162ec44e45d63f2840a3aaef2 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 23 Feb 2023 16:17:59 +0100 Subject: [PATCH 28/93] cast VikujGroups directly to []map[string]interface{} changug []models.Team to []*models.Team --- pkg/modules/auth/openid/openid.go | 79 +++++++++++++++---------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 876c703f5..7166dc659 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -60,11 +60,11 @@ type Provider struct { Oauth2Config *oauth2.Config `json:"-"` } type claims struct { - Email string `json:"email"` - Name string `json:"name"` - PreferredUsername string `json:"preferred_username"` - Nickname string `json:"nickname"` - VikunjaGroups interface{} `json:"vikunja_groups"` + Email string `json:"email"` + Name string `json:"name"` + PreferredUsername string `json:"preferred_username"` + Nickname string `json:"nickname"` + VikunjaGroups []map[string]interface{} `json:"vikunja_groups"` } func init() { @@ -277,41 +277,37 @@ func SignOutFromTeamsByID(s *xorm.Session, u *user.User, teamIDs []int64) (errs return errs } -func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []models.TeamData, errs []error) { +func getTeamDataFromToken(groups []map[string]interface{}, provider *Provider) (teamData []models.TeamData, errs []error) { teamData = []models.TeamData{} errs = []error{} - if groups != nil { - el := groups.([]interface{}) - for _, data := range el { - team := data.(map[string]interface{}) - var name string - var description string - var oidcID string - if team["name"] != nil { - name = team["name"].(string) - } - if team["description"] != nil { - description = team["description"].(string) - } - if team["oidcID"] != nil { - switch t := team["oidcID"].(type) { - case int64: - oidcID = strconv.FormatInt(team["oidcID"].(int64), 10) - case string: - oidcID = string(team["oidcID"].(string)) - case float64: - oidcID = strconv.FormatFloat(team["oidcID"].(float64), 'f', -1, 64) - default: - log.Errorf("No oidcID assigned for %v or type %v not supported", team, t) - } - } - if name == "" || oidcID == "" { - log.Errorf("Claim of your custom scope does not hold name or oidcID for automatic group assignment through oidc provider. Please check %s", provider.Name) - errs = append(errs, &user.ErrOpenIDCustomScopeMalformed{}) - continue - } - teamData = append(teamData, models.TeamData{TeamName: name, OidcID: oidcID, Description: description}) + for _, team := range groups { + var name string + var description string + var oidcID string + if team["name"] != nil { + name = team["name"].(string) } + if team["description"] != nil { + description = team["description"].(string) + } + if team["oidcID"] != nil { + switch t := team["oidcID"].(type) { + case int64: + oidcID = strconv.FormatInt(team["oidcID"].(int64), 10) + case string: + oidcID = string(team["oidcID"].(string)) + case float64: + oidcID = strconv.FormatFloat(team["oidcID"].(float64), 'f', -1, 64) + default: + log.Errorf("No oidcID assigned for %v or type %v not supported", team, t) + } + } + if name == "" || oidcID == "" { + log.Errorf("Claim of your custom scope does not hold name or oidcID for automatic group assignment through oidc provider. Please check %s", provider.Name) + errs = append(errs, &user.ErrOpenIDCustomScopeMalformed{}) + continue + } + teamData = append(teamData, models.TeamData{TeamName: name, OidcID: oidcID, Description: description}) } return teamData, errs } @@ -327,8 +323,8 @@ func CreateTeamWithData(s *xorm.Session, teamData models.TeamData, u *user.User) } // this functions creates an array of existing teams that was generated from the oidc data. -func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.TeamData, u *user.User) (te []models.Team, err error) { - te = []models.Team{} +func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.TeamData, u *user.User) (te []*models.Team, err error) { + te = []*models.Team{} // Procedure can only be successful if oidcID is set and converted to string for _, oidcTeam := range teamData { team, err := models.GetTeamByOidcIDAndName(s, oidcTeam.OidcID, oidcTeam.TeamName) @@ -338,12 +334,11 @@ func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.TeamData, if err != nil { return te, err } - te = append(te, *newTeam) + te = append(te, newTeam) } else { log.Debugf("Team with oidc_id %v and name %v already exists.", team.OidcID, team.Name) - te = append(te, team) + te = append(te, &team) } - } return te, err } -- 2.45.1 From a3e4449b7b3b9df428c3083ff96e4580911347df Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 23 Feb 2023 16:32:20 +0100 Subject: [PATCH 29/93] change too generic name TeamData struct to OIDCTeamData --- pkg/models/teams.go | 4 ++-- pkg/modules/auth/openid/openid.go | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 0e30971cc..c1f470f92 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -94,8 +94,8 @@ type TeamUser struct { TeamID int64 `json:"-"` } -// TeamData is the relevant data for a team and is delivered by oidc token -type TeamData struct { +// OIDCTeamData is the relevant data for a team and is delivered by oidc token +type OIDCTeamData struct { TeamName string OidcID string Description string diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 7166dc659..ed1b735fd 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -231,7 +231,7 @@ func HandleCallback(c echo.Context) error { return auth.NewUserAuthTokenResponse(u, c, false) } -func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.TeamData) (oidcTeams []int64, err error) { +func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.OIDCTeamData) (oidcTeams []int64, err error) { if len(teamData) > 0 { // check if we have seen these teams before. // find or create Teams and assign user as teammember. @@ -277,8 +277,8 @@ func SignOutFromTeamsByID(s *xorm.Session, u *user.User, teamIDs []int64) (errs return errs } -func getTeamDataFromToken(groups []map[string]interface{}, provider *Provider) (teamData []models.TeamData, errs []error) { - teamData = []models.TeamData{} +func getTeamDataFromToken(groups []map[string]interface{}, provider *Provider) (teamData []models.OIDCTeamData, errs []error) { + teamData = []models.OIDCTeamData{} errs = []error{} for _, team := range groups { var name string @@ -307,12 +307,12 @@ func getTeamDataFromToken(groups []map[string]interface{}, provider *Provider) ( errs = append(errs, &user.ErrOpenIDCustomScopeMalformed{}) continue } - teamData = append(teamData, models.TeamData{TeamName: name, OidcID: oidcID, Description: description}) + teamData = append(teamData, models.OIDCTeamData{TeamName: name, OidcID: oidcID, Description: description}) } return teamData, errs } -func CreateTeamWithData(s *xorm.Session, teamData models.TeamData, u *user.User) (team *models.Team, err error) { +func CreateTeamWithData(s *xorm.Session, teamData models.OIDCTeamData, u *user.User) (team *models.Team, err error) { tea := &models.Team{ Name: teamData.TeamName, Description: teamData.Description, @@ -323,7 +323,7 @@ func CreateTeamWithData(s *xorm.Session, teamData models.TeamData, u *user.User) } // this functions creates an array of existing teams that was generated from the oidc data. -func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.TeamData, u *user.User) (te []*models.Team, err error) { +func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.OIDCTeamData, u *user.User) (te []*models.Team, err error) { te = []*models.Team{} // Procedure can only be successful if oidcID is set and converted to string for _, oidcTeam := range teamData { -- 2.45.1 From 061c2a4b7e5a699d3db28ffe8230cd81d6eed432 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 10 Mar 2023 13:46:18 +0100 Subject: [PATCH 30/93] remove left over function GetMemberCount, rename function SignOut to RemoveFrom --- pkg/models/team_members.go | 9 --------- pkg/modules/auth/openid/openid.go | 4 ++-- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index edc9632df..9bcd06426 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -115,15 +115,6 @@ func (tm *TeamMember) CheckMembership(s *xorm.Session) (exists bool, err error) return exists, err } -func (tm *TeamMember) GetMemberCount(s *xorm.Session) (memberCount int64, err error) { - member := TeamMember{} - memberCount, err = s. - Where("team_id = ?", tm.TeamID). - Cols("user_id"). - Count(&member) - return memberCount, err -} - // Update toggles a team member's admin status // @Summary Toggle a team member's admin status // @Description If a user is team admin, this will make them member and vise-versa. diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index ed1b735fd..e48971474 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -216,7 +216,7 @@ func HandleCallback(c echo.Context) error { if err != nil { log.Errorf("Could not proceed with group routine %v", err) } - errs = SignOutFromTeamsByID(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + errs = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) log.Errorf("%v", errs) for _, err := range errs { log.Errorf("Found Error while signing out from teams %v", err) @@ -255,7 +255,7 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models. return oidcTeams, err } -func SignOutFromTeamsByID(s *xorm.Session, u *user.User, teamIDs []int64) (errs []error) { +func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (errs []error) { errs = []error{} for _, teamID := range teamIDs { tm := models.TeamMember{TeamID: teamID, UserID: u.ID, Username: u.Username} -- 2.45.1 From 1ad439f02915c1c06af39a5797f11a0fa0b83f66 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 30 Mar 2023 17:15:24 +0200 Subject: [PATCH 31/93] return single team for GetTeamByOidcIDAndName --- pkg/models/teams.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/models/teams.go b/pkg/models/teams.go index c1f470f92..bf1a44eed 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -20,7 +20,6 @@ import ( "time" "code.vikunja.io/api/pkg/db" - "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/events" "code.vikunja.io/api/pkg/user" @@ -151,15 +150,16 @@ func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { // GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters // For oidc team creation oidcID and Name need to be set func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (team Team, err error) { - exists, err := s. + err = s. Table("teams"). Where("oidc_id = ? AND name = ?", oidcID, teamName). - Get(&team) - log.Debugf("GetTeamByOidcIDAndName: %v, exists: %v", team.Name, exists) - if exists && err == nil { - return team, nil + OrderBy("name ASC"). + Limit(1). + Find(&team) + if err != nil { + return team, ErrOIDCTeamDoesNotExist{teamName, oidcID} } - return team, ErrOIDCTeamDoesNotExist{teamName, oidcID} + return team, err } func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err error) { -- 2.45.1 From 74990b88fa900899593d1f608bdfeed9653368ba Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 8 May 2023 15:41:24 +0200 Subject: [PATCH 32/93] fix limit GetTeamByOidcIDAndName to get a single team --- pkg/models/teams.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/models/teams.go b/pkg/models/teams.go index bf1a44eed..8150144b1 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -150,13 +150,13 @@ func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { // GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters // For oidc team creation oidcID and Name need to be set func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (team Team, err error) { - err = s. + has, err := s. Table("teams"). Where("oidc_id = ? AND name = ?", oidcID, teamName). - OrderBy("name ASC"). + Asc("id"). Limit(1). - Find(&team) - if err != nil { + Get(&team) + if !has || err != nil { return team, ErrOIDCTeamDoesNotExist{teamName, oidcID} } return team, err -- 2.45.1 From ffa894ecd184b450c19b5840f69ef58742bad2dc Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 8 May 2023 15:42:02 +0200 Subject: [PATCH 33/93] work on instructions for openid.md --- pkg/modules/auth/openid/openid.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/modules/auth/openid/openid.md b/pkg/modules/auth/openid/openid.md index c63a89c22..f8e7a7c8b 100644 --- a/pkg/modules/auth/openid/openid.md +++ b/pkg/modules/auth/openid/openid.md @@ -1,8 +1,10 @@ # Assign teams via oidc -This PR adds the functionality to assign users to teams via oidc. +Adds the functionality to assign users to teams via oidc. Read carefully and brief your administrators to use this feature. +You need to configure your oidc provider as explained in the documentation below to make this feature work. Tested with oidc provider authentik. -To distinguish between teams created in vikunja and teams generated via oidc, an attribute for vikunja teams is introduced, which is called: *oidcID* +To distinguish between teams created in vikunja and teams generated via oidc, a string attribute for vikunja teams is introduced, which is called: *oidcID* +You should conigure your provider to send an oidcID to vikunja. ## Setup -- 2.45.1 From d345fbb1d4f0035da86d247bb4811946c894a967 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 8 May 2023 15:51:58 +0200 Subject: [PATCH 34/93] work on openid to just start group workflow when teamData is available --- pkg/modules/auth/openid/openid.go | 78 ++++++++++++++++--------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index e48971474..fe1bb9552 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -203,23 +203,24 @@ func HandleCallback(c echo.Context) error { // does the oidc token contain well formed "vikunja_groups" through vikunja_scope teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, provider) - for _, err := range errs { - log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) - } + if teamData != nil { + for _, err := range errs { + log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) + } - //find old teams for user through oidc - oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) - if err != nil { - log.Errorf("No Oidc Teams found for user %v", err) - } - oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) - if err != nil { - log.Errorf("Could not proceed with group routine %v", err) - } - errs = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) - log.Errorf("%v", errs) - for _, err := range errs { - log.Errorf("Found Error while signing out from teams %v", err) + //find old teams for user through oidc + oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) + if err != nil { + log.Errorf("No Oidc Teams found for user %v", err) + } + oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) + if err != nil { + log.Errorf("Could not proceed with group routine %v", err) + } + errs = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + for _, err := range errs { + log.Errorf("Found Error while signing out from teams %v", err) + } } err = s.Commit() if err != nil { @@ -232,29 +233,30 @@ func HandleCallback(c echo.Context) error { } func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.OIDCTeamData) (oidcTeams []int64, err error) { - if len(teamData) > 0 { - // check if we have seen these teams before. - // find or create Teams and assign user as teammember. - teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u) - if err != nil { - log.Errorf("Error verifying team for %v, got %v. Error: %v", u.Name, teams, err) - return nil, err - } - for _, team := range teams { - tm := models.TeamMember{TeamID: team.ID, UserID: u.ID, Username: u.Username} - exists, _ := tm.CheckMembership(s) - if !exists { - err = tm.Create(s, u) - if err != nil { - log.Errorf("Could not assign %v to %v. %v", u.Username, team.Name, err) - } + if len(teamData) == 0 { + return + } + // check if we have seen these teams before. + // find or create Teams and assign user as teammember. + teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u) + if err != nil { + log.Errorf("Error verifying team for %v, got %v. Error: %v", u.Name, teams, err) + return nil, err + } + for _, team := range teams { + tm := models.TeamMember{TeamID: team.ID, UserID: u.ID, Username: u.Username} + exists, _ := tm.CheckMembership(s) + if !exists { + err = tm.Create(s, u) + if err != nil { + log.Errorf("Could not assign %v to %v. %v", u.Username, team.Name, err) } - oidcTeams = append(oidcTeams, team.ID) } + oidcTeams = append(oidcTeams, team.ID) } return oidcTeams, err - } + func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (errs []error) { errs = []error{} for _, teamID := range teamIDs { @@ -313,19 +315,19 @@ func getTeamDataFromToken(groups []map[string]interface{}, provider *Provider) ( } func CreateTeamWithData(s *xorm.Session, teamData models.OIDCTeamData, u *user.User) (team *models.Team, err error) { - tea := &models.Team{ + team = &models.Team{ Name: teamData.TeamName, Description: teamData.Description, OidcID: teamData.OidcID, } - err = tea.Create(s, u) - return tea, err + err = team.Create(s, u) + return team, err } // this functions creates an array of existing teams that was generated from the oidc data. func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.OIDCTeamData, u *user.User) (te []*models.Team, err error) { te = []*models.Team{} - // Procedure can only be successful if oidcID is set and converted to string + // Procedure can only be successful if oidcID is set for _, oidcTeam := range teamData { team, err := models.GetTeamByOidcIDAndName(s, oidcTeam.OidcID, oidcTeam.TeamName) if err != nil { -- 2.45.1 From 01a56019e9df6e3e3c2ea420ded013c34e68ea73 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 8 May 2023 16:04:49 +0200 Subject: [PATCH 35/93] refactor unused function GetTeamsByName --- pkg/models/error.go | 27 ++------------------------- pkg/models/teams.go | 18 ------------------ 2 files changed, 2 insertions(+), 43 deletions(-) diff --git a/pkg/models/error.go b/pkg/models/error.go index 2b6772ff7..df701cc9f 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1177,29 +1177,6 @@ func (err ErrTeamDoesNotHaveAccessToProject) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusForbidden, Code: ErrCodeTeamDoesNotHaveAccessToProject, Message: "This team does not have access to the project."} } -// ErrTeamsDoNotExist represents an error where Teams searched via non-unique name do not exist. -type ErrTeamsDoNotExist struct { - Name string -} - -// IsErrTeamsDoNotExist checks if an error is ErrTeamsDoNotExist. -func IsErrTeamsDoNotExist(err error) bool { - _, ok := err.(ErrTeamsDoNotExist) - return ok -} - -func (err ErrTeamsDoNotExist) Error() string { - return fmt.Sprintf("No teams with that name exist [Team Name: %v]", err.Name) -} - -// ErrCodeTeamsDoesNotExist holds the unique world-error code of this error -const ErrCodeTeamsDoNotExist = 6008 - -// HTTPError holds the http error description -func (err ErrTeamsDoNotExist) HTTPError() web.HTTPError { - return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No teams with that name exist"} -} - // ErrOIDCTeamDoesNotExist represents an error where a team with specified name and specified oidcId property does not exist type ErrOIDCTeamDoesNotExist struct { OidcID string @@ -1218,7 +1195,7 @@ func (err ErrOIDCTeamDoesNotExist) Error() string { } // ErrCodeTeamDoesNotExist holds the unique world-error code of this error -const ErrCodeOIDCTeamDoesNotExist = 6009 +const ErrCodeOIDCTeamDoesNotExist = 6008 // HTTPError holds the http error description func (err ErrOIDCTeamDoesNotExist) HTTPError() web.HTTPError { @@ -1241,7 +1218,7 @@ func (err ErrOIDCTeamsDoNotExistForUser) Error() string { } // ErrCodeTeamDoesNotExist holds the unique world-error code of this error -const ErrCodeOIDCTeamsDoNotExistForUser = 6010 +const ErrCodeOIDCTeamsDoNotExistForUser = 6009 // HTTPError holds the http error description func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError { diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 8150144b1..eba74450f 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -129,24 +129,6 @@ func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) { return } -// GetTeamByName gets teams by name -func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { - if name == "" { - return teams, ErrTeamsDoNotExist{name} - } - - var ts []*Team - - err = s. - Where("name = ?", name). - Find(&ts) - if err != nil || len(ts) == 0 { - return ts, ErrTeamsDoNotExist{name} - } - teams = ts - return teams, err -} - // GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters // For oidc team creation oidcID and Name need to be set func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (team Team, err error) { -- 2.45.1 From ed91d6744ed41ca770750df80e2cbcb83978a0ba Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 12 Oct 2022 15:11:45 +0200 Subject: [PATCH 36/93] introduce functionality to assign/create team via group claim --- pkg/models/error.go | 26 +++++++++++++ pkg/models/teams.go | 61 ++++++++++++++++++++++++++++++- pkg/modules/auth/openid/openid.go | 3 ++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/pkg/models/error.go b/pkg/models/error.go index df701cc9f..d127839c4 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1081,7 +1081,33 @@ func (err ErrTeamDoesNotExist) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "This team does not exist."} } +<<<<<<< HEAD // ErrTeamAlreadyHasAccess represents an error where a team already has access to a project +======= +type ErrTeamsDoNotExist struct { + Name string +} + +// IsErrTeamDoNotExist checks if an error is ErrTeamDoesNotExist. +func IsErrTeamsDoNotExist(err error) bool { + _, ok := err.(ErrTeamsDoNotExist) + return ok +} + +func (err ErrTeamsDoNotExist) Error() string { + return fmt.Sprintf("Team does not exist [Team Name: %v]", err.Name) +} + +// ErrCodeTeamDoesNotExist holds the unique world-error code of this error +const ErrCodeTeamsDoNotExist = 6002 + +// HTTPError holds the http error description +func (err ErrTeamsDoNotExist) HTTPError() web.HTTPError { + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No team with given name exists."} +} + +// ErrTeamAlreadyHasAccess represents an error where a team already has access to a list/namespace +>>>>>>> 2715a556... introduce functionality to assign/create team via group claim type ErrTeamAlreadyHasAccess struct { TeamID int64 ID int64 diff --git a/pkg/models/teams.go b/pkg/models/teams.go index eba74450f..905fad480 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -81,7 +81,7 @@ type TeamMember struct { } // TableName makes beautiful table names -func (*TeamMember) TableName() string { +func (TeamMember) TableName() string { return "team_members" } @@ -128,6 +128,34 @@ func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) { return } +func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { + if name == "" { + return teams, ErrTeamsDoNotExist{name} + } + + var ts []*Team + + exists := s. + Where("name = ?", name). + Find(&ts) + if exists != nil { + return + } + if len(ts) == 0 { + return ts, ErrTeamsDoNotExist{name} + } + + // //for each ts + // teamSlice := []*Team{ts} + // err = addMoreInfoToTeams(s, teamSlice) + // if err != nil { + // return + // } + + teams = ts + + return +} // GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters // For oidc team creation oidcID and Name need to be set @@ -319,6 +347,37 @@ func (t *Team) Create(s *xorm.Session, a web.Auth) (err error) { }) } +func (t *Team) CreateNoAdmin(s *xorm.Session, a web.Auth) (err error) { + doer, err := user.GetFromAuth(a) + if err != nil { + return err + } + + // Check if we have a name + if t.Name == "" { + return ErrTeamNameCannotBeEmpty{} + } + + t.CreatedByID = doer.ID + t.CreatedBy = doer + + _, err = s.Insert(t) + if err != nil { + return + } + + // Insert the current user as member and admin + tm := TeamMember{TeamID: t.ID, Username: doer.Username, Admin: false} + if err = tm.Create(s, doer); err != nil { + return err + } + + return events.Dispatch(&TeamCreatedEvent{ + Team: t, + Doer: a, + }) +} + // Delete deletes a team // @Summary Deletes a team // @Description Delets a team. This will also remove the access for all users in that team. diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index fe1bb9552..315edb7c3 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -195,6 +195,9 @@ func HandleCallback(c echo.Context) error { // Check if we have seen this user before u, err := getOrCreateUser(s, cl, idToken.Issuer, idToken.Subject) + + log.Errorf("Issuer %s: %v", idToken.Issuer, err) + if err != nil { _ = s.Rollback() log.Errorf("Error creating new user for provider %s: %v", provider.Name, err) -- 2.45.1 From 95ce28b6e58fd875891f078ddab1340de8191f79 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 7 Dec 2022 15:32:58 +0100 Subject: [PATCH 37/93] wip assign groups via oidc --- pkg/models/team_members.go | 2 +- pkg/models/teams.go | 40 ++++--------------------------- pkg/modules/auth/openid/openid.go | 2 -- 3 files changed, 5 insertions(+), 39 deletions(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index 9bcd06426..7d2e99afe 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -53,7 +53,7 @@ func (tm *TeamMember) Create(s *xorm.Session, a web.Auth) (err error) { // Check if that user is already part of the team exists, err := s. - Where("team_id = ? AND user_id = ?", tm.TeamID, tm.UserID). + Where("team_id = ? AND user_name = ?", tm.TeamID, tm.UserID). Get(&TeamMember{}) if err != nil { return diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 905fad480..0143b66e8 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -128,6 +128,8 @@ func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) { return } + +// GetTeamByID gets teams by name func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { if name == "" { return teams, ErrTeamsDoNotExist{name} @@ -144,14 +146,6 @@ func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { if len(ts) == 0 { return ts, ErrTeamsDoNotExist{name} } - - // //for each ts - // teamSlice := []*Team{ts} - // err = addMoreInfoToTeams(s, teamSlice) - // if err != nil { - // return - // } - teams = ts return @@ -347,35 +341,9 @@ func (t *Team) Create(s *xorm.Session, a web.Auth) (err error) { }) } -func (t *Team) CreateNoAdmin(s *xorm.Session, a web.Auth) (err error) { - doer, err := user.GetFromAuth(a) - if err != nil { - return err - } - - // Check if we have a name - if t.Name == "" { - return ErrTeamNameCannotBeEmpty{} - } - - t.CreatedByID = doer.ID - t.CreatedBy = doer - - _, err = s.Insert(t) - if err != nil { - return - } - +func (t *Team) ManageAdminRight(teamMember TeamMember, admin bool) { // Insert the current user as member and admin - tm := TeamMember{TeamID: t.ID, Username: doer.Username, Admin: false} - if err = tm.Create(s, doer); err != nil { - return err - } - - return events.Dispatch(&TeamCreatedEvent{ - Team: t, - Doer: a, - }) + teamMember.Admin = admin } // Delete deletes a team diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 315edb7c3..191bc747c 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -196,8 +196,6 @@ func HandleCallback(c echo.Context) error { // Check if we have seen this user before u, err := getOrCreateUser(s, cl, idToken.Issuer, idToken.Subject) - log.Errorf("Issuer %s: %v", idToken.Issuer, err) - if err != nil { _ = s.Rollback() log.Errorf("Error creating new user for provider %s: %v", provider.Name, err) -- 2.45.1 From 044bb07e9d14ef5b2cdf7a2bcca5574dab889a4e Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:31:43 +0100 Subject: [PATCH 38/93] add OidcIDto teams --- pkg/models/team_members.go | 2 +- pkg/models/teams.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index 7d2e99afe..9bcd06426 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -53,7 +53,7 @@ func (tm *TeamMember) Create(s *xorm.Session, a web.Auth) (err error) { // Check if that user is already part of the team exists, err := s. - Where("team_id = ? AND user_name = ?", tm.TeamID, tm.UserID). + Where("team_id = ? AND user_id = ?", tm.TeamID, tm.UserID). Get(&TeamMember{}) if err != nil { return diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 0143b66e8..ac74fd49c 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -20,6 +20,7 @@ import ( "time" "code.vikunja.io/api/pkg/db" + "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/events" "code.vikunja.io/api/pkg/user" -- 2.45.1 From 9fce32c7e933663070aa8741b026677635bc477e Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:33:45 +0100 Subject: [PATCH 39/93] add functionality of searching teams by oidcId and name to teams.go --- pkg/models/teams.go | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/pkg/models/teams.go b/pkg/models/teams.go index ac74fd49c..4c1fc3916 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -130,7 +130,7 @@ func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) { return } -// GetTeamByID gets teams by name +// GetTeamByName gets teams by name func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { if name == "" { return teams, ErrTeamsDoNotExist{name} @@ -138,18 +138,28 @@ func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { var ts []*Team - exists := s. + err = s. Where("name = ?", name). Find(&ts) - if exists != nil { - return - } - if len(ts) == 0 { + if err != nil || len(ts) == 0 { return ts, ErrTeamsDoNotExist{name} } teams = ts + return teams, err +} - return +// GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters +// For oidc team creation oidcID and Name need to be set +func GetTeamByOidcIDAndName(s *xorm.Session, id string, name string) (team Team, err error) { + exists, err := s. + Table("teams"). + Where("oidc_id = ? AND name = ?", id, name). + Get(&team) + log.Debugf("GetTeamByOidcIDAndName: %v, exists: %v", team.Name, exists) + if exists && err == nil { + return team, nil + } + return team, ErrTeamsDoNotExist{id} } // GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters -- 2.45.1 From 905df6ebc0c177282c38d0831a28a34521c045f2 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:41:30 +0100 Subject: [PATCH 40/93] add TeamData struct to openid.go --- pkg/modules/auth/openid/openid.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 191bc747c..cc0d2fd9c 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -59,6 +59,11 @@ type Provider struct { openIDProvider *oidc.Provider Oauth2Config *oauth2.Config `json:"-"` } +type TeamData struct { + TeamName string + OidcID string + Description string +} type claims struct { Email string `json:"email"` Name string `json:"name"` -- 2.45.1 From ac032400d6365a696a250d279bc5ae4ac3b873ac Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:49:19 +0100 Subject: [PATCH 41/93] add functionality to assign user to teams through oidc custom claim --- pkg/modules/auth/openid/openid.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index cc0d2fd9c..eda4fc633 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -228,6 +228,7 @@ func HandleCallback(c echo.Context) error { log.Errorf("Found Error while signing out from teams %v", err) } } + err = s.Commit() if err != nil { _ = s.Rollback() @@ -347,7 +348,9 @@ func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.OIDCTeamD log.Debugf("Team with oidc_id %v and name %v already exists.", team.OidcID, team.Name) te = append(te, &team) } + } + log.Debugf("Array: %v", te) return te, err } -- 2.45.1 From 0c3a12bcf7a943c299abdc06c59319fbbc56312c Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 13:49:30 +0100 Subject: [PATCH 42/93] do the swag --- pkg/swagger/docs.go | 13 +++++++++++++ pkg/swagger/swagger.json | 13 +++++++++++++ pkg/swagger/swagger.yaml | 10 ++++++++++ 3 files changed, 36 insertions(+) diff --git a/pkg/swagger/docs.go b/pkg/swagger/docs.go index 590a4e7ca..59123e5d4 100644 --- a/pkg/swagger/docs.go +++ b/pkg/swagger/docs.go @@ -8300,6 +8300,11 @@ const docTemplate = `{ "maxLength": 250, "minLength": 1 }, + "oidc_id": { + "description": "The team's oidc id delivered by the oidc provider", + "type": "string", + "maxLength": 250 + }, "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" @@ -8430,6 +8435,11 @@ const docTemplate = `{ "maxLength": 250, "minLength": 1 }, + "oidc_id": { + "description": "The team's oidc id delivered by the oidc provider", + "type": "string", + "maxLength": 250 + }, "right": { "$ref": "#/definitions/models.Right" }, @@ -8573,6 +8583,9 @@ const docTemplate = `{ }, "name": { "type": "string" + }, + "scope": { + "type": "string" } } }, diff --git a/pkg/swagger/swagger.json b/pkg/swagger/swagger.json index d03f3a34a..dcb4d07d9 100644 --- a/pkg/swagger/swagger.json +++ b/pkg/swagger/swagger.json @@ -8292,6 +8292,11 @@ "maxLength": 250, "minLength": 1 }, + "oidc_id": { + "description": "The team's oidc id delivered by the oidc provider", + "type": "string", + "maxLength": 250 + }, "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" @@ -8422,6 +8427,11 @@ "maxLength": 250, "minLength": 1 }, + "oidc_id": { + "description": "The team's oidc id delivered by the oidc provider", + "type": "string", + "maxLength": 250 + }, "right": { "$ref": "#/definitions/models.Right" }, @@ -8565,6 +8575,9 @@ }, "name": { "type": "string" + }, + "scope": { + "type": "string" } } }, diff --git a/pkg/swagger/swagger.yaml b/pkg/swagger/swagger.yaml index 32bbdada6..08eeb64f7 100644 --- a/pkg/swagger/swagger.yaml +++ b/pkg/swagger/swagger.yaml @@ -904,6 +904,10 @@ definitions: maxLength: 250 minLength: 1 type: string + oidc_id: + description: The team's oidc id delivered by the oidc provider + maxLength: 250 + type: string updated: description: A timestamp when this relation was last updated. You cannot change this value. @@ -1007,6 +1011,10 @@ definitions: maxLength: 250 minLength: 1 type: string + oidc_id: + description: The team's oidc id delivered by the oidc provider + maxLength: 250 + type: string right: $ref: '#/definitions/models.Right' updated: @@ -1116,6 +1124,8 @@ definitions: type: string name: type: string + scope: + type: string type: object todoist.Migration: properties: -- 2.45.1 From 274dbecae5d34f0407584ebcae04133fd75f4e0b Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 16:53:14 +0100 Subject: [PATCH 43/93] change method function to GetOrCreateTeamsByOIDCAndNames --- pkg/modules/auth/openid/openid.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index eda4fc633..dcda192a0 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -208,10 +208,19 @@ func HandleCallback(c echo.Context) error { } // does the oidc token contain well formed "vikunja_groups" through vikunja_scope - teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, provider) - if teamData != nil { - for _, err := range errs { - log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) + teamData, err := getTeamDataFromToken(cl.VikunjaGroups, provider) + if err != nil { + log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) + return handler.HandleHTTPError(err, c) + } + // check if we have seen these teams before. + // find or create Teams and assign user as teammember. + if len(teamData) > 0 { + log.Debugf("TeamData is set %v", teamData) + teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u) + if err != nil { + log.Errorf("Error verifying team for name %v, got %v", cl.Name, teams, err) + return err } //find old teams for user through oidc -- 2.45.1 From 12242d9c6f01f9a7bde8deff90f68de54e8aaf90 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Jan 2023 17:15:50 +0100 Subject: [PATCH 44/93] add functionality for deleting user only from oidc teams which are not present in the current token --- pkg/models/error.go | 71 ++++++++++++++++++++----------- pkg/models/teams.go | 20 +++++++-- pkg/modules/auth/openid/openid.go | 33 ++++++++++++-- 3 files changed, 92 insertions(+), 32 deletions(-) diff --git a/pkg/models/error.go b/pkg/models/error.go index d127839c4..e17e0b240 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1081,33 +1081,7 @@ func (err ErrTeamDoesNotExist) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "This team does not exist."} } -<<<<<<< HEAD -// ErrTeamAlreadyHasAccess represents an error where a team already has access to a project -======= -type ErrTeamsDoNotExist struct { - Name string -} - -// IsErrTeamDoNotExist checks if an error is ErrTeamDoesNotExist. -func IsErrTeamsDoNotExist(err error) bool { - _, ok := err.(ErrTeamsDoNotExist) - return ok -} - -func (err ErrTeamsDoNotExist) Error() string { - return fmt.Sprintf("Team does not exist [Team Name: %v]", err.Name) -} - -// ErrCodeTeamDoesNotExist holds the unique world-error code of this error -const ErrCodeTeamsDoNotExist = 6002 - -// HTTPError holds the http error description -func (err ErrTeamsDoNotExist) HTTPError() web.HTTPError { - return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No team with given name exists."} -} - // ErrTeamAlreadyHasAccess represents an error where a team already has access to a list/namespace ->>>>>>> 2715a556... introduce functionality to assign/create team via group claim type ErrTeamAlreadyHasAccess struct { TeamID int64 ID int64 @@ -1251,6 +1225,51 @@ func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Teams with property oidcId could be found for User."} } +type ErrTeamsDoNotExist struct { + Name string +} + +// IsErrTeamDoNotExist checks if an error is ErrTeamDoesNotExist. +func IsErrTeamsDoNotExist(err error) bool { + _, ok := err.(ErrTeamsDoNotExist) + return ok +} + +func (err ErrTeamsDoNotExist) Error() string { + return fmt.Sprintf("Team does not exist [Team Name: %v]", err.Name) +} + +// ErrCodeTeamDoesNotExist holds the unique world-error code of this error +const ErrCodeTeamsDoNotExist = 6008 + +// HTTPError holds the http error description +func (err ErrTeamsDoNotExist) HTTPError() web.HTTPError { + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No team with given name exists."} +} + +// ErrOIDCTeamsDoNotExistForUser represents an error where an oidcTeam does not exist for the user +type ErrOIDCTeamsDoNotExistForUser struct { + UserID int64 +} + +// IsErrOIDCTeamsDoNotExistForUser checks if an error is ErrOIDCTeamsDoNotExistForUser. +func IsErrOIDCTeamsDoNotExistForUser(err error) bool { + _, ok := err.(ErrTeamDoesNotExist) + return ok +} + +func (err ErrOIDCTeamsDoNotExistForUser) Error() string { + return fmt.Sprintf("No Oidc exists for User [User ID: %d]", err.UserID) +} + +// ErrCodeTeamDoesNotExist holds the unique world-error code of this error +const ErrCodeOIDCTeamsDoNotExistForUser = 6009 + +// HTTPError holds the http error description +func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError { + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "This team does not exist."} +} + // ==================== // User <-> Project errors // ==================== diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 4c1fc3916..b9450cef6 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -150,16 +150,30 @@ func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { // GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters // For oidc team creation oidcID and Name need to be set -func GetTeamByOidcIDAndName(s *xorm.Session, id string, name string) (team Team, err error) { +func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (team Team, err error) { exists, err := s. Table("teams"). - Where("oidc_id = ? AND name = ?", id, name). + Where("oidc_id = ? AND name = ?", oidcID, teamName). Get(&team) log.Debugf("GetTeamByOidcIDAndName: %v, exists: %v", team.Name, exists) if exists && err == nil { return team, nil } - return team, ErrTeamsDoNotExist{id} + return team, ErrTeamsDoNotExist{oidcID} +} + +func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err error) { + err = s. + Table("team_members"). + Where("user_id = ? ", userID). + Join("RIGHT", "teams", "teams.id = team_members.team_id"). + Where("teams.oidc_id != ?", ""). + Cols("teams.id"). + Find(&ts) + if ts == nil || err != nil { + return ts, ErrOIDCTeamsDoNotExistForUser{userID} + } + return ts, nil } // GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index dcda192a0..dd3956276 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -213,9 +213,16 @@ func HandleCallback(c echo.Context) error { log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) return handler.HandleHTTPError(err, c) } - // check if we have seen these teams before. - // find or create Teams and assign user as teammember. + + //TODO: fix this error check + // nil is no problem + if len(teamData) > 0 { + //find old teams for user through oidc + oldOidcTeams, _ := models.FindAllOidcTeamIDsForUser(s, u.ID) + // check if we have seen these teams before. + // find or create Teams and assign user as teammember. + var oidcTeams []int64 log.Debugf("TeamData is set %v", teamData) teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u) if err != nil { @@ -236,8 +243,8 @@ func HandleCallback(c echo.Context) error { for _, err := range errs { log.Errorf("Found Error while signing out from teams %v", err) } + SignOutFromOrDeleteTeamsByID(s, u, notIn(oldOidcTeams, oidcTeams)) } - err = s.Commit() if err != nil { _ = s.Rollback() @@ -430,3 +437,23 @@ func getOrCreateUser(s *xorm.Session, cl *claims, issuer, subject string) (u *us return } + +// find the elements which appear in slice1,but not in slice2 +func notIn(slice1 []int64, slice2 []int64) []int64 { + var diff []int64 + + for _, s1 := range slice1 { + found := false + for _, s2 := range slice2 { + if s1 == s2 { + found = true + break + } + } + // String not found. We add it to return slice + if !found { + diff = append(diff, s1) + } + } + return diff +} -- 2.45.1 From 6d24e356711b822026bf1b5753c9b923134f3f4f Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 1 Feb 2023 16:35:12 +0100 Subject: [PATCH 45/93] remove user from all oidc teams if token is empty --- pkg/modules/auth/openid/openid.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index dd3956276..50db45436 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -214,15 +214,12 @@ func HandleCallback(c echo.Context) error { return handler.HandleHTTPError(err, c) } - //TODO: fix this error check - // nil is no problem - + //find old teams for user through oidc + oldOidcTeams, _ := models.FindAllOidcTeamIDsForUser(s, u.ID) + var oidcTeams []int64 if len(teamData) > 0 { - //find old teams for user through oidc - oldOidcTeams, _ := models.FindAllOidcTeamIDsForUser(s, u.ID) // check if we have seen these teams before. // find or create Teams and assign user as teammember. - var oidcTeams []int64 log.Debugf("TeamData is set %v", teamData) teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u) if err != nil { @@ -243,8 +240,8 @@ func HandleCallback(c echo.Context) error { for _, err := range errs { log.Errorf("Found Error while signing out from teams %v", err) } - SignOutFromOrDeleteTeamsByID(s, u, notIn(oldOidcTeams, oidcTeams)) } + SignOutFromOrDeleteTeamsByID(s, u, notIn(oldOidcTeams, oidcTeams)) err = s.Commit() if err != nil { _ = s.Rollback() -- 2.45.1 From 8652cf987417d9147d68a5f0cedbd2247af4399f Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 1 Feb 2023 16:35:27 +0100 Subject: [PATCH 46/93] add config.yml.sample for seting up vikunja_scope and group assignment feature --- config.yml.sample | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config.yml.sample b/config.yml.sample index fbef4b629..d0f9db6d1 100644 --- a/config.yml.sample +++ b/config.yml.sample @@ -6,7 +6,7 @@ service: # The duration of the issued JWT tokens in seconds. # The default is 259200 seconds (3 Days). jwtttl: 259200 - # The duration of the "remember me" time in seconds. When the login request is made with + # The duration of the "remember me" time in seconds. When the login request is made with # the long param set, the token returned will be valid for this period. # The default is 2592000 seconds (30 Days). jwtttllong: 2592000 @@ -48,7 +48,7 @@ service: # If enabled, vikunja will send an email to everyone who is either assigned to a task or created it when a task reminder # is due. enableemailreminders: true - # If true, will allow users to request the complete deletion of their account. When using external authentication methods + # If true, will allow users to request the complete deletion of their account. When using external authentication methods # it may be required to coordinate with them in order to delete the account. This setting will not affect the cli commands # for user deletion. enableuserdeletion: true @@ -109,7 +109,7 @@ database: typesense: # Whether to enable the Typesense integration. If true, all tasks will be synced to the configured Typesense # instance and all search and filtering will run through Typesense instead of only through the database. - # Typesense allows fast fulltext search including fuzzy matching support. It may return different results than + # Typesense allows fast fulltext search including fuzzy matching support. It may return different results than # what you'd get with a database-only search. enabled: false # The url to the Typesense instance you want to use. Can be hosted locally or in Typesense Cloud as long -- 2.45.1 From 263250a7050648784800691c5dd729043cdce584 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 1 Feb 2023 16:36:01 +0100 Subject: [PATCH 47/93] add openid.md as readme for feature: 950 assigning group through oidc claim --- pkg/modules/auth/openid/openid.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/pkg/modules/auth/openid/openid.md b/pkg/modules/auth/openid/openid.md index f8e7a7c8b..94399e5fe 100644 --- a/pkg/modules/auth/openid/openid.md +++ b/pkg/modules/auth/openid/openid.md @@ -1,14 +1,14 @@ +regarding: +https://kolaente.dev/vikunja/api/pulls/1279 + # Assign teams via oidc -Adds the functionality to assign users to teams via oidc. +This PR adds the functionality to assign users to teams via oidc. Read carefully and brief your administrators to use this feature. -You need to configure your oidc provider as explained in the documentation below to make this feature work. Tested with oidc provider authentik. -To distinguish between teams created in vikunja and teams generated via oidc, a string attribute for vikunja teams is introduced, which is called: *oidcID* -You should conigure your provider to send an oidcID to vikunja. +To distinguish between groups created in vikunja and groups generated via oidc, there is an attribute neccessary, which is called: *oidcID* ## Setup - -Edit [config.yml](https://kolaente.dev/vikunja/api/src/branch/main/config.yml.sample) to include scope: openid profile email vikunja_scope +Edit config.yml to include scope: openid profile email vikunja_scope For authentik to use group assignment feature: - go to: .../if/admin/#/core/property-mappings @@ -50,12 +50,21 @@ You should see "the description you entered in the oidc provider's admin area" - You will see "(sso: XXXXX)" written next to each team you were asigned through oidc. -## IMPORTANT NOTES: +## IMPORTANT NOTES: +<<<<<<< HEAD * **SSO/OIDC teams cannot be edited.** * **It is crucial to call the element "vikunja_groups" since this is the name vikunja is looking for.** * **Additionally, make sure to deliver an "oidcID" and a "name".** +======= +**SSO/OIDC teams cannot be edited.** + +**It is crucial to call the element "vikunja_groups" since this is the name vikunja is looking for.** + +**Additionally, make sure to deliver an "oidcID" and a "name".** + +>>>>>>> 8d46490d... add openid.md as readme for feature: 950 assigning group through oidc claim @@ -89,7 +98,7 @@ nothing happens You'll get error. Custom Scope malformed "The custom scope set by the OIDC provider is malformed. Please make sure the openid provider sets the data correctly for your scope. Check especially to have set an oidcID." - + 7. *In Vikunja I am in "team 3" with oidcID "", but the token does not deliver any data for "team 3":* \ You will stay in team 3 since it was not set by the oidc provider -- 2.45.1 From e9d69925670bc556f1cd1802e270eeb5c9f82122 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 10 Feb 2023 21:44:08 +0100 Subject: [PATCH 48/93] do the swag --- pkg/swagger/docs.go | 517 +++++++++++++++++++++++--------- pkg/swagger/swagger.json | 614 +++++++++++++++++++++------------------ pkg/swagger/swagger.yaml | 419 ++++++++++++++++---------- 3 files changed, 966 insertions(+), 584 deletions(-) diff --git a/pkg/swagger/docs.go b/pkg/swagger/docs.go index 59123e5d4..60e21cce5 100644 --- a/pkg/swagger/docs.go +++ b/pkg/swagger/docs.go @@ -7272,11 +7272,36 @@ const docTemplate = `{ }, "created_by": { "description": "The user who initially created the bucket.", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" + }, + "filter_by": { + "description": "The field name of the field to filter by", + "type": "array", + "items": { + "type": "string" + } + }, + "filter_comparator": { + "description": "The comparator for field and value", + "type": "array", + "items": { + "type": "string" + } + }, + "filter_concat": { + "description": "The way all filter conditions are concatenated together, can be either \"and\" or \"or\".,", + "type": "string" + }, + "filter_include_nulls": { + "description": "If set to true, the result will also include null values", + "type": "boolean" + }, + "filter_value": { + "description": "The value of the field name to filter by", + "type": "array", + "items": { + "type": "string" + } }, "id": { "description": "The unique, numeric id of this bucket.", @@ -7287,13 +7312,36 @@ const docTemplate = `{ "type": "integer", "minimum": 0 }, +<<<<<<< HEAD +======= + "list_id": { + "description": "The list this bucket belongs to.", + "type": "integer" + }, + "order_by": { + "description": "The query parameter to order the items by. This can be either asc or desc, with asc being the default.", + "type": "array", + "items": { + "type": "string" + } + }, +>>>>>>> 4567a680... do the swag "position": { "description": "The position this bucket has when querying all buckets. See the tasks.position property on how to use this.", "type": "number" }, +<<<<<<< HEAD "project_id": { "description": "The project this bucket belongs to.", "type": "integer" +======= + "sort_by": { + "description": "The query parameter to sort by. This is for ex. done, priority, etc.", + "type": "array", + "items": { + "type": "string" + } +>>>>>>> 4567a680... do the swag }, "tasks": { "description": "All tasks which belong to this bucket.", @@ -7310,7 +7358,9 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this bucket was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.BulkAssignees": { @@ -7322,7 +7372,9 @@ const docTemplate = `{ "items": { "$ref": "#/definitions/user.User" } - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.BulkTask": { @@ -7356,11 +7408,7 @@ const docTemplate = `{ }, "created_by": { "description": "The user who initially created the task.", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "description": { "description": "The task description.", @@ -7432,11 +7480,7 @@ const docTemplate = `{ }, "related_tasks": { "description": "All related tasks, grouped by their relation kind", - "allOf": [ - { - "$ref": "#/definitions/models.RelatedTaskMap" - } - ] + "$ref": "#/definitions/models.RelatedTaskMap" }, "reminders": { "description": "An array of reminders that are associated with this task.", @@ -7451,23 +7495,24 @@ const docTemplate = `{ }, "repeat_mode": { "description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.", - "allOf": [ - { - "$ref": "#/definitions/models.TaskRepeatMode" - } - ] + "type": "integer" }, "start_date": { "description": "When this task starts.", "type": "string" }, "subscription": { +<<<<<<< HEAD "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retrieving one task.", "allOf": [ { "$ref": "#/definitions/models.Subscription" } ] +======= + "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.", + "$ref": "#/definitions/models.Subscription" +>>>>>>> 4567a680... do the swag }, "task_ids": { "description": "A project of task ids to update", @@ -7484,7 +7529,9 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this task was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.DatabaseNotifications": { @@ -7512,7 +7559,9 @@ const docTemplate = `{ "read_at": { "description": "When this notification is marked as read, this will be updated with the current timestamp.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.Label": { @@ -7524,11 +7573,7 @@ const docTemplate = `{ }, "created_by": { "description": "The user who created this label", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "description": { "description": "The label description.", @@ -7552,7 +7597,9 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this label was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.LabelTask": { @@ -7565,7 +7612,9 @@ const docTemplate = `{ "label_id": { "description": "The label id you want to associate with a task.", "type": "integer" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.LabelTaskBulk": { @@ -7577,7 +7626,9 @@ const docTemplate = `{ "items": { "$ref": "#/definitions/models.Label" } - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.LinkSharing": { @@ -7604,37 +7655,40 @@ const docTemplate = `{ "type": "string" }, "right": { +<<<<<<< HEAD "description": "The right this project is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", +======= + "description": "The right this list is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", +>>>>>>> 4567a680... do the swag "default": 0, - "maximum": 2, - "allOf": [ - { - "$ref": "#/definitions/models.Right" - } - ] + "maximum": 2 }, "shared_by": { +<<<<<<< HEAD "description": "The user who shared this project", "allOf": [ { "$ref": "#/definitions/user.User" } ] +======= + "description": "The user who shared this list", + "$ref": "#/definitions/user.User" +>>>>>>> 4567a680... do the swag }, "sharing_type": { "description": "The kind of this link. 0 = undefined, 1 = without password, 2 = with password.", + "type": "integer", "default": 0, - "maximum": 2, - "allOf": [ - { - "$ref": "#/definitions/models.SharingType" - } - ] + "maximum": 2 }, "updated": { "description": "A timestamp when this share was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.Message": { @@ -7696,12 +7750,17 @@ const docTemplate = `{ "type": "boolean" }, "owner": { +<<<<<<< HEAD "description": "The user who created this project.", "allOf": [ { "$ref": "#/definitions/user.User" } ] +======= + "description": "The user who created this list.", + "$ref": "#/definitions/user.User" +>>>>>>> 4567a680... do the swag }, "parent_project_id": { "type": "integer" @@ -7711,12 +7770,17 @@ const docTemplate = `{ "type": "number" }, "subscription": { +<<<<<<< HEAD "description": "The subscription status for the user reading this project. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one project.", "allOf": [ { "$ref": "#/definitions/models.Subscription" } ] +======= + "description": "The subscription status for the user reading this list. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one list.", + "$ref": "#/definitions/models.Subscription" +>>>>>>> 4567a680... do the swag }, "title": { "description": "The title of the project. You'll see this in the overview.", @@ -7727,9 +7791,12 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this project was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, +<<<<<<< HEAD "models.ProjectDuplicate": { "type": "object", "properties": { @@ -7745,6 +7812,105 @@ const docTemplate = `{ "description": "The target parent project", "type": "integer" } +======= + "models.ListDuplicate": { + "type": "object", + "properties": { + "list": { + "description": "The copied list", + "$ref": "#/definitions/models.List" + }, + "namespace_id": { + "description": "The target namespace ID", + "type": "integer" + }, + "web.CRUDable": {}, + "web.Rights": {} + } + }, + "models.ListUser": { + "type": "object", + "properties": { + "created": { + "description": "A timestamp when this relation was created. You cannot change this value.", + "type": "string" + }, + "id": { + "description": "The unique, numeric id of this list \u003c-\u003e user relation.", + "type": "integer" + }, + "right": { + "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", + "default": 0, + "maximum": 2 + }, + "updated": { + "description": "A timestamp when this relation was last updated. You cannot change this value.", + "type": "string" + }, + "user_id": { + "description": "The username.", + "type": "string" + }, + "web.CRUDable": {}, + "web.Rights": {} + } + }, + "models.Message": { + "type": "object", + "properties": { + "message": { + "description": "A standard message.", + "type": "string" + } + } + }, + "models.Namespace": { + "type": "object", + "properties": { + "created": { + "description": "A timestamp when this namespace was created. You cannot change this value.", + "type": "string" + }, + "description": { + "description": "The description of the namespace", + "type": "string" + }, + "hex_color": { + "description": "The hex color of this namespace", + "type": "string", + "maxLength": 6 + }, + "id": { + "description": "The unique, numeric id of this namespace.", + "type": "integer" + }, + "is_archived": { + "description": "Whether or not a namespace is archived.", + "type": "boolean" + }, + "owner": { + "description": "The user who owns this namespace", + "$ref": "#/definitions/user.User" + }, + "subscription": { + "description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.", + "$ref": "#/definitions/models.Subscription" + }, + "title": { + "description": "The name of this namespace.", + "type": "string", + "maxLength": 250, + "minLength": 1 + }, + "updated": { + "description": "A timestamp when this namespace was last updated. You cannot change this value.", + "type": "string" + }, + "web.CRUDable": {}, + "web.Rights": {} +>>>>>>> 4567a680... do the swag } }, "models.ProjectUser": { @@ -7760,13 +7926,9 @@ const docTemplate = `{ }, "right": { "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", "default": 0, - "maximum": 2, - "allOf": [ - { - "$ref": "#/definitions/models.Right" - } - ] + "maximum": 2 }, "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", @@ -7775,9 +7937,66 @@ const docTemplate = `{ "user_id": { "description": "The username.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, +<<<<<<< HEAD +======= + "models.NamespaceWithLists": { + "type": "object", + "properties": { + "created": { + "description": "A timestamp when this namespace was created. You cannot change this value.", + "type": "string" + }, + "description": { + "description": "The description of the namespace", + "type": "string" + }, + "hex_color": { + "description": "The hex color of this namespace", + "type": "string", + "maxLength": 6 + }, + "id": { + "description": "The unique, numeric id of this namespace.", + "type": "integer" + }, + "is_archived": { + "description": "Whether or not a namespace is archived.", + "type": "boolean" + }, + "lists": { + "type": "array", + "items": { + "$ref": "#/definitions/models.List" + } + }, + "owner": { + "description": "The user who owns this namespace", + "$ref": "#/definitions/user.User" + }, + "subscription": { + "description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.", + "$ref": "#/definitions/models.Subscription" + }, + "title": { + "description": "The name of this namespace.", + "type": "string", + "maxLength": 250, + "minLength": 1 + }, + "updated": { + "description": "A timestamp when this namespace was last updated. You cannot change this value.", + "type": "string" + }, + "web.CRUDable": {}, + "web.Rights": {} + } + }, +>>>>>>> 4567a680... do the swag "models.RelatedTaskMap": { "type": "object", "additionalProperties": { @@ -7787,6 +8006,7 @@ const docTemplate = `{ } } }, +<<<<<<< HEAD "models.RelationKind": { "type": "string", "enum": [ @@ -7855,6 +8075,8 @@ const docTemplate = `{ } } }, +======= +>>>>>>> 4567a680... do the swag "models.SavedFilter": { "type": "object", "properties": { @@ -7868,11 +8090,7 @@ const docTemplate = `{ }, "filters": { "description": "The actual filters this filter contains", - "allOf": [ - { - "$ref": "#/definitions/models.TaskCollection" - } - ] + "$ref": "#/definitions/models.TaskCollection" }, "id": { "description": "The unique numeric id of this saved filter", @@ -7884,11 +8102,7 @@ const docTemplate = `{ }, "owner": { "description": "The user who owns this filter", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "title": { "description": "The title of the filter.", @@ -7899,22 +8113,11 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this filter was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, - "models.SharingType": { - "type": "integer", - "enum": [ - 0, - 1, - 2 - ], - "x-enum-varnames": [ - "SharingTypeUnknown", - "SharingTypeWithoutPassword", - "SharingTypeWithPassword" - ] - }, "models.Subscription": { "type": "object", "properties": { @@ -7935,12 +8138,10 @@ const docTemplate = `{ }, "user": { "description": "The user who made this subscription", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] - } + "$ref": "#/definitions/user.User" + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.Task": { @@ -7974,11 +8175,7 @@ const docTemplate = `{ }, "created_by": { "description": "The user who initially created the task.", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "description": { "description": "The task description.", @@ -8050,11 +8247,7 @@ const docTemplate = `{ }, "related_tasks": { "description": "All related tasks, grouped by their relation kind", - "allOf": [ - { - "$ref": "#/definitions/models.RelatedTaskMap" - } - ] + "$ref": "#/definitions/models.RelatedTaskMap" }, "reminders": { "description": "An array of reminders that are associated with this task.", @@ -8069,23 +8262,15 @@ const docTemplate = `{ }, "repeat_mode": { "description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.", - "allOf": [ - { - "$ref": "#/definitions/models.TaskRepeatMode" - } - ] + "type": "integer" }, "start_date": { "description": "When this task starts.", "type": "string" }, "subscription": { - "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retrieving one task.", - "allOf": [ - { - "$ref": "#/definitions/models.Subscription" - } - ] + "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.", + "$ref": "#/definitions/models.Subscription" }, "title": { "description": "The task text. This is what you'll see in the project.", @@ -8095,7 +8280,9 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this task was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TaskAssginee": { @@ -8106,7 +8293,9 @@ const docTemplate = `{ }, "user_id": { "type": "integer" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TaskAttachment": { @@ -8126,7 +8315,9 @@ const docTemplate = `{ }, "task_id": { "type": "integer" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TaskCollection": { @@ -8174,7 +8365,9 @@ const docTemplate = `{ "items": { "type": "string" } - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TaskComment": { @@ -8194,7 +8387,9 @@ const docTemplate = `{ }, "updated": { "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TaskRelation": { @@ -8206,11 +8401,7 @@ const docTemplate = `{ }, "created_by": { "description": "The user who created this relation", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "other_task_id": { "description": "The ID of the other task, the task which is being related.", @@ -8218,18 +8409,17 @@ const docTemplate = `{ }, "relation_kind": { "description": "The kind of the relation.", - "allOf": [ - { - "$ref": "#/definitions/models.RelationKind" - } - ] + "type": "string" }, "task_id": { "description": "The ID of the \"base\" task, the task which has a relation to another.", "type": "integer" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, +<<<<<<< HEAD "models.TaskReminder": { "type": "object", "properties": { @@ -8264,6 +8454,8 @@ const docTemplate = `{ "TaskRepeatModeFromCurrentDate" ] }, +======= +>>>>>>> 4567a680... do the swag "models.Team": { "type": "object", "properties": { @@ -8273,11 +8465,7 @@ const docTemplate = `{ }, "created_by": { "description": "The user who created this team.", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "description": { "description": "The team's description.", @@ -8308,9 +8496,43 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, +<<<<<<< HEAD +======= + "models.TeamList": { + "type": "object", + "properties": { + "created": { + "description": "A timestamp when this relation was created. You cannot change this value.", + "type": "string" + }, + "id": { + "description": "The unique, numeric id of this list \u003c-\u003e team relation.", + "type": "integer" + }, + "right": { + "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", + "default": 0, + "maximum": 2 + }, + "team_id": { + "description": "The team id.", + "type": "integer" + }, + "updated": { + "description": "A timestamp when this relation was last updated. You cannot change this value.", + "type": "string" + }, + "web.CRUDable": {}, + "web.Rights": {} + } + }, +>>>>>>> 4567a680... do the swag "models.TeamMember": { "type": "object", "properties": { @@ -8329,7 +8551,9 @@ const docTemplate = `{ "username": { "description": "The username of the member. We use this to prevent automated user id entering.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TeamProject": { @@ -8345,13 +8569,9 @@ const docTemplate = `{ }, "right": { "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", "default": 0, - "maximum": 2, - "allOf": [ - { - "$ref": "#/definitions/models.Right" - } - ] + "maximum": 2 }, "team_id": { "description": "The team id.", @@ -8360,7 +8580,9 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TeamUser": { @@ -8396,7 +8618,8 @@ const docTemplate = `{ "type": "string", "maxLength": 250, "minLength": 1 - } + }, + "web.Auth": {} } }, "models.TeamWithRight": { @@ -8408,11 +8631,7 @@ const docTemplate = `{ }, "created_by": { "description": "The user who created this team.", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "description": { "description": "The team's description.", @@ -8441,12 +8660,16 @@ const docTemplate = `{ "maxLength": 250 }, "right": { - "$ref": "#/definitions/models.Right" + "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", + "default": 0 }, "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.UserWithRight": { @@ -8470,7 +8693,9 @@ const docTemplate = `{ "type": "string" }, "right": { - "$ref": "#/definitions/models.Right" + "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", + "default": 0 }, "updated": { "description": "A timestamp when this task was last updated. You cannot change this value.", @@ -8481,7 +8706,8 @@ const docTemplate = `{ "type": "string", "maxLength": 250, "minLength": 1 - } + }, + "web.Auth": {} } }, "models.Webhook": { @@ -8763,7 +8989,8 @@ const docTemplate = `{ "type": "string", "maxLength": 250, "minLength": 1 - } + }, + "web.Auth": {} } }, "v1.LinkShareAuth": { diff --git a/pkg/swagger/swagger.json b/pkg/swagger/swagger.json index dcb4d07d9..a01eae950 100644 --- a/pkg/swagger/swagger.json +++ b/pkg/swagger/swagger.json @@ -7264,11 +7264,36 @@ }, "created_by": { "description": "The user who initially created the bucket.", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" + }, + "filter_by": { + "description": "The field name of the field to filter by", + "type": "array", + "items": { + "type": "string" + } + }, + "filter_comparator": { + "description": "The comparator for field and value", + "type": "array", + "items": { + "type": "string" + } + }, + "filter_concat": { + "description": "The way all filter conditions are concatenated together, can be either \"and\" or \"or\".,", + "type": "string" + }, + "filter_include_nulls": { + "description": "If set to true, the result will also include null values", + "type": "boolean" + }, + "filter_value": { + "description": "The value of the field name to filter by", + "type": "array", + "items": { + "type": "string" + } }, "id": { "description": "The unique, numeric id of this bucket.", @@ -7279,13 +7304,27 @@ "type": "integer", "minimum": 0 }, + "list_id": { + "description": "The list this bucket belongs to.", + "type": "integer" + }, + "order_by": { + "description": "The query parameter to order the items by. This can be either asc or desc, with asc being the default.", + "type": "array", + "items": { + "type": "string" + } + }, "position": { "description": "The position this bucket has when querying all buckets. See the tasks.position property on how to use this.", "type": "number" }, - "project_id": { - "description": "The project this bucket belongs to.", - "type": "integer" + "sort_by": { + "description": "The query parameter to sort by. This is for ex. done, priority, etc.", + "type": "array", + "items": { + "type": "string" + } }, "tasks": { "description": "All tasks which belong to this bucket.", @@ -7302,7 +7341,9 @@ "updated": { "description": "A timestamp when this bucket was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.BulkAssignees": { @@ -7314,7 +7355,9 @@ "items": { "$ref": "#/definitions/user.User" } - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.BulkTask": { @@ -7348,11 +7391,7 @@ }, "created_by": { "description": "The user who initially created the task.", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "description": { "description": "The task description.", @@ -7424,11 +7463,7 @@ }, "related_tasks": { "description": "All related tasks, grouped by their relation kind", - "allOf": [ - { - "$ref": "#/definitions/models.RelatedTaskMap" - } - ] + "$ref": "#/definitions/models.RelatedTaskMap" }, "reminders": { "description": "An array of reminders that are associated with this task.", @@ -7443,23 +7478,15 @@ }, "repeat_mode": { "description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.", - "allOf": [ - { - "$ref": "#/definitions/models.TaskRepeatMode" - } - ] + "type": "integer" }, "start_date": { "description": "When this task starts.", "type": "string" }, "subscription": { - "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retrieving one task.", - "allOf": [ - { - "$ref": "#/definitions/models.Subscription" - } - ] + "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.", + "$ref": "#/definitions/models.Subscription" }, "task_ids": { "description": "A project of task ids to update", @@ -7476,7 +7503,9 @@ "updated": { "description": "A timestamp when this task was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.DatabaseNotifications": { @@ -7504,7 +7533,9 @@ "read_at": { "description": "When this notification is marked as read, this will be updated with the current timestamp.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.Label": { @@ -7516,11 +7547,7 @@ }, "created_by": { "description": "The user who created this label", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "description": { "description": "The label description.", @@ -7544,7 +7571,9 @@ "updated": { "description": "A timestamp when this label was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.LabelTask": { @@ -7557,7 +7586,9 @@ "label_id": { "description": "The label id you want to associate with a task.", "type": "integer" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.LabelTaskBulk": { @@ -7569,7 +7600,9 @@ "items": { "$ref": "#/definitions/models.Label" } - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.LinkSharing": { @@ -7596,37 +7629,27 @@ "type": "string" }, "right": { - "description": "The right this project is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "description": "The right this list is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", "default": 0, - "maximum": 2, - "allOf": [ - { - "$ref": "#/definitions/models.Right" - } - ] + "maximum": 2 }, "shared_by": { - "description": "The user who shared this project", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "description": "The user who shared this list", + "$ref": "#/definitions/user.User" }, "sharing_type": { "description": "The kind of this link. 0 = undefined, 1 = without password, 2 = with password.", + "type": "integer", "default": 0, - "maximum": 2, - "allOf": [ - { - "$ref": "#/definitions/models.SharingType" - } - ] + "maximum": 2 }, "updated": { "description": "A timestamp when this share was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.Message": { @@ -7688,12 +7711,8 @@ "type": "boolean" }, "owner": { - "description": "The user who created this project.", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "description": "The user who created this list.", + "$ref": "#/definitions/user.User" }, "parent_project_id": { "type": "integer" @@ -7703,12 +7722,8 @@ "type": "number" }, "subscription": { - "description": "The subscription status for the user reading this project. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one project.", - "allOf": [ - { - "$ref": "#/definitions/models.Subscription" - } - ] + "description": "The subscription status for the user reading this list. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one list.", + "$ref": "#/definitions/models.Subscription" }, "title": { "description": "The title of the project. You'll see this in the overview.", @@ -7719,24 +7734,108 @@ "updated": { "description": "A timestamp when this project was last updated. You cannot change this value.", "type": "string" + }, + "web.CRUDable": {}, + "web.Rights": {} + } + }, + "models.ListDuplicate": { + "type": "object", + "properties": { + "list": { + "description": "The copied list", + "$ref": "#/definitions/models.List" + }, + "namespace_id": { + "description": "The target namespace ID", + "type": "integer" + }, + "web.CRUDable": {}, + "web.Rights": {} + } + }, + "models.ListUser": { + "type": "object", + "properties": { + "created": { + "description": "A timestamp when this relation was created. You cannot change this value.", + "type": "string" + }, + "id": { + "description": "The unique, numeric id of this list \u003c-\u003e user relation.", + "type": "integer" + }, + "right": { + "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", + "default": 0, + "maximum": 2 + }, + "updated": { + "description": "A timestamp when this relation was last updated. You cannot change this value.", + "type": "string" + }, + "user_id": { + "description": "The username.", + "type": "string" + }, + "web.CRUDable": {}, + "web.Rights": {} + } + }, + "models.Message": { + "type": "object", + "properties": { + "message": { + "description": "A standard message.", + "type": "string" } } }, - "models.ProjectDuplicate": { + "models.Namespace": { "type": "object", "properties": { - "duplicated_project": { - "description": "The copied project", - "allOf": [ - { - "$ref": "#/definitions/models.Project" - } - ] + "created": { + "description": "A timestamp when this namespace was created. You cannot change this value.", + "type": "string" }, - "parent_project_id": { - "description": "The target parent project", + "description": { + "description": "The description of the namespace", + "type": "string" + }, + "hex_color": { + "description": "The hex color of this namespace", + "type": "string", + "maxLength": 6 + }, + "id": { + "description": "The unique, numeric id of this namespace.", "type": "integer" - } + }, + "is_archived": { + "description": "Whether or not a namespace is archived.", + "type": "boolean" + }, + "owner": { + "description": "The user who owns this namespace", + "$ref": "#/definitions/user.User" + }, + "subscription": { + "description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.", + "$ref": "#/definitions/models.Subscription" + }, + "title": { + "description": "The name of this namespace.", + "type": "string", + "maxLength": 250, + "minLength": 1 + }, + "updated": { + "description": "A timestamp when this namespace was last updated. You cannot change this value.", + "type": "string" + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.ProjectUser": { @@ -7752,13 +7851,9 @@ }, "right": { "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", "default": 0, - "maximum": 2, - "allOf": [ - { - "$ref": "#/definitions/models.Right" - } - ] + "maximum": 2 }, "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", @@ -7767,7 +7862,61 @@ "user_id": { "description": "The username.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} + } + }, + "models.NamespaceWithLists": { + "type": "object", + "properties": { + "created": { + "description": "A timestamp when this namespace was created. You cannot change this value.", + "type": "string" + }, + "description": { + "description": "The description of the namespace", + "type": "string" + }, + "hex_color": { + "description": "The hex color of this namespace", + "type": "string", + "maxLength": 6 + }, + "id": { + "description": "The unique, numeric id of this namespace.", + "type": "integer" + }, + "is_archived": { + "description": "Whether or not a namespace is archived.", + "type": "boolean" + }, + "lists": { + "type": "array", + "items": { + "$ref": "#/definitions/models.List" + } + }, + "owner": { + "description": "The user who owns this namespace", + "$ref": "#/definitions/user.User" + }, + "subscription": { + "description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.", + "$ref": "#/definitions/models.Subscription" + }, + "title": { + "description": "The name of this namespace.", + "type": "string", + "maxLength": 250, + "minLength": 1 + }, + "updated": { + "description": "A timestamp when this namespace was last updated. You cannot change this value.", + "type": "string" + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.RelatedTaskMap": { @@ -7779,74 +7928,6 @@ } } }, - "models.RelationKind": { - "type": "string", - "enum": [ - "unknown", - "subtask", - "parenttask", - "related", - "duplicateof", - "duplicates", - "blocking", - "blocked", - "precedes", - "follows", - "copiedfrom", - "copiedto" - ], - "x-enum-varnames": [ - "RelationKindUnknown", - "RelationKindSubtask", - "RelationKindParenttask", - "RelationKindRelated", - "RelationKindDuplicateOf", - "RelationKindDuplicates", - "RelationKindBlocking", - "RelationKindBlocked", - "RelationKindPreceeds", - "RelationKindFollows", - "RelationKindCopiedFrom", - "RelationKindCopiedTo" - ] - }, - "models.ReminderRelation": { - "type": "string", - "enum": [ - "due_date", - "start_date", - "end_date" - ], - "x-enum-varnames": [ - "ReminderRelationDueDate", - "ReminderRelationStartDate", - "ReminderRelationEndDate" - ] - }, - "models.Right": { - "type": "integer", - "enum": [ - 0, - 1, - 2 - ], - "x-enum-varnames": [ - "RightRead", - "RightWrite", - "RightAdmin" - ] - }, - "models.RouteDetail": { - "type": "object", - "properties": { - "method": { - "type": "string" - }, - "path": { - "type": "string" - } - } - }, "models.SavedFilter": { "type": "object", "properties": { @@ -7860,11 +7941,7 @@ }, "filters": { "description": "The actual filters this filter contains", - "allOf": [ - { - "$ref": "#/definitions/models.TaskCollection" - } - ] + "$ref": "#/definitions/models.TaskCollection" }, "id": { "description": "The unique numeric id of this saved filter", @@ -7876,11 +7953,7 @@ }, "owner": { "description": "The user who owns this filter", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "title": { "description": "The title of the filter.", @@ -7891,22 +7964,11 @@ "updated": { "description": "A timestamp when this filter was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, - "models.SharingType": { - "type": "integer", - "enum": [ - 0, - 1, - 2 - ], - "x-enum-varnames": [ - "SharingTypeUnknown", - "SharingTypeWithoutPassword", - "SharingTypeWithPassword" - ] - }, "models.Subscription": { "type": "object", "properties": { @@ -7927,12 +7989,10 @@ }, "user": { "description": "The user who made this subscription", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] - } + "$ref": "#/definitions/user.User" + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.Task": { @@ -7966,11 +8026,7 @@ }, "created_by": { "description": "The user who initially created the task.", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "description": { "description": "The task description.", @@ -8042,11 +8098,7 @@ }, "related_tasks": { "description": "All related tasks, grouped by their relation kind", - "allOf": [ - { - "$ref": "#/definitions/models.RelatedTaskMap" - } - ] + "$ref": "#/definitions/models.RelatedTaskMap" }, "reminders": { "description": "An array of reminders that are associated with this task.", @@ -8061,23 +8113,15 @@ }, "repeat_mode": { "description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.", - "allOf": [ - { - "$ref": "#/definitions/models.TaskRepeatMode" - } - ] + "type": "integer" }, "start_date": { "description": "When this task starts.", "type": "string" }, "subscription": { - "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retrieving one task.", - "allOf": [ - { - "$ref": "#/definitions/models.Subscription" - } - ] + "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.", + "$ref": "#/definitions/models.Subscription" }, "title": { "description": "The task text. This is what you'll see in the project.", @@ -8087,7 +8131,9 @@ "updated": { "description": "A timestamp when this task was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TaskAssginee": { @@ -8098,7 +8144,9 @@ }, "user_id": { "type": "integer" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TaskAttachment": { @@ -8118,7 +8166,9 @@ }, "task_id": { "type": "integer" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TaskCollection": { @@ -8166,7 +8216,9 @@ "items": { "type": "string" } - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TaskComment": { @@ -8186,7 +8238,9 @@ }, "updated": { "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TaskRelation": { @@ -8198,11 +8252,7 @@ }, "created_by": { "description": "The user who created this relation", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "other_task_id": { "description": "The ID of the other task, the task which is being related.", @@ -8210,52 +8260,16 @@ }, "relation_kind": { "description": "The kind of the relation.", - "allOf": [ - { - "$ref": "#/definitions/models.RelationKind" - } - ] + "type": "string" }, "task_id": { "description": "The ID of the \"base\" task, the task which has a relation to another.", "type": "integer" - } - } - }, - "models.TaskReminder": { - "type": "object", - "properties": { - "relative_period": { - "description": "A period in seconds relative to another date argument. Negative values mean the reminder triggers before the date. Default: 0, tiggers when RelativeTo is due.", - "type": "integer" }, - "relative_to": { - "description": "The name of the date field to which the relative period refers to.", - "allOf": [ - { - "$ref": "#/definitions/models.ReminderRelation" - } - ] - }, - "reminder": { - "description": "The absolute time when the user wants to be reminded of the task.", - "type": "string" - } + "web.CRUDable": {}, + "web.Rights": {} } }, - "models.TaskRepeatMode": { - "type": "integer", - "enum": [ - 0, - 1, - 2 - ], - "x-enum-varnames": [ - "TaskRepeatModeDefault", - "TaskRepeatModeMonth", - "TaskRepeatModeFromCurrentDate" - ] - }, "models.Team": { "type": "object", "properties": { @@ -8265,11 +8279,7 @@ }, "created_by": { "description": "The user who created this team.", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "description": { "description": "The team's description.", @@ -8300,7 +8310,38 @@ "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} + } + }, + "models.TeamList": { + "type": "object", + "properties": { + "created": { + "description": "A timestamp when this relation was created. You cannot change this value.", + "type": "string" + }, + "id": { + "description": "The unique, numeric id of this list \u003c-\u003e team relation.", + "type": "integer" + }, + "right": { + "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", + "default": 0, + "maximum": 2 + }, + "team_id": { + "description": "The team id.", + "type": "integer" + }, + "updated": { + "description": "A timestamp when this relation was last updated. You cannot change this value.", + "type": "string" + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TeamMember": { @@ -8321,7 +8362,9 @@ "username": { "description": "The username of the member. We use this to prevent automated user id entering.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TeamProject": { @@ -8337,13 +8380,9 @@ }, "right": { "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", "default": 0, - "maximum": 2, - "allOf": [ - { - "$ref": "#/definitions/models.Right" - } - ] + "maximum": 2 }, "team_id": { "description": "The team id.", @@ -8352,7 +8391,9 @@ "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.TeamUser": { @@ -8388,7 +8429,8 @@ "type": "string", "maxLength": 250, "minLength": 1 - } + }, + "web.Auth": {} } }, "models.TeamWithRight": { @@ -8400,11 +8442,7 @@ }, "created_by": { "description": "The user who created this team.", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] + "$ref": "#/definitions/user.User" }, "description": { "description": "The team's description.", @@ -8433,12 +8471,16 @@ "maxLength": 250 }, "right": { - "$ref": "#/definitions/models.Right" + "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", + "default": 0 }, "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - } + }, + "web.CRUDable": {}, + "web.Rights": {} } }, "models.UserWithRight": { @@ -8462,7 +8504,9 @@ "type": "string" }, "right": { - "$ref": "#/definitions/models.Right" + "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "type": "integer", + "default": 0 }, "updated": { "description": "A timestamp when this task was last updated. You cannot change this value.", @@ -8473,7 +8517,8 @@ "type": "string", "maxLength": 250, "minLength": 1 - } + }, + "web.Auth": {} } }, "models.Webhook": { @@ -8755,7 +8800,8 @@ "type": "string", "maxLength": 250, "minLength": 1 - } + }, + "web.Auth": {} } }, "v1.LinkShareAuth": { diff --git a/pkg/swagger/swagger.yaml b/pkg/swagger/swagger.yaml index 08eeb64f7..0f7c23ea9 100644 --- a/pkg/swagger/swagger.yaml +++ b/pkg/swagger/swagger.yaml @@ -109,9 +109,30 @@ definitions: value. type: string created_by: - allOf: - - $ref: '#/definitions/user.User' + $ref: '#/definitions/user.User' description: The user who initially created the bucket. + filter_by: + description: The field name of the field to filter by + items: + type: string + type: array + filter_comparator: + description: The comparator for field and value + items: + type: string + type: array + filter_concat: + description: The way all filter conditions are concatenated together, can + be either "and" or "or"., + type: string + filter_include_nulls: + description: If set to true, the result will also include null values + type: boolean + filter_value: + description: The value of the field name to filter by + items: + type: string + type: array id: description: The unique, numeric id of this bucket. type: integer @@ -119,13 +140,25 @@ definitions: description: How many tasks can be at the same time on this board max minimum: 0 type: integer + list_id: + description: The list this bucket belongs to. + type: integer + order_by: + description: The query parameter to order the items by. This can be either + asc or desc, with asc being the default. + items: + type: string + type: array position: description: The position this bucket has when querying all buckets. See the tasks.position property on how to use this. type: number - project_id: - description: The project this bucket belongs to. - type: integer + sort_by: + description: The query parameter to sort by. This is for ex. done, priority, + etc. + items: + type: string + type: array tasks: description: All tasks which belong to this bucket. items: @@ -139,6 +172,8 @@ definitions: description: A timestamp when this bucket was last updated. You cannot change this value. type: string + web.CRUDable: {} + web.Rights: {} type: object models.BulkAssignees: properties: @@ -147,6 +182,8 @@ definitions: items: $ref: '#/definitions/user.User' type: array + web.CRUDable: {} + web.Rights: {} type: object models.BulkTask: properties: @@ -172,8 +209,7 @@ definitions: value. type: string created_by: - allOf: - - $ref: '#/definitions/user.User' + $ref: '#/definitions/user.User' description: The user who initially created the task. description: description: The task description. @@ -238,8 +274,7 @@ definitions: description: The project this task belongs to. type: integer related_tasks: - allOf: - - $ref: '#/definitions/models.RelatedTaskMap' + $ref: '#/definitions/models.RelatedTaskMap' description: All related tasks, grouped by their relation kind reminders: description: An array of reminders that are associated with this task. @@ -252,18 +287,16 @@ definitions: increase all remindes and the due date by its amount. type: integer repeat_mode: - allOf: - - $ref: '#/definitions/models.TaskRepeatMode' description: 'Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.' + type: integer start_date: description: When this task starts. type: string subscription: - allOf: - - $ref: '#/definitions/models.Subscription' + $ref: '#/definitions/models.Subscription' description: |- The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it. Will only returned when retrieving one task. @@ -280,6 +313,8 @@ definitions: description: A timestamp when this task was last updated. You cannot change this value. type: string + web.CRUDable: {} + web.Rights: {} type: object models.DatabaseNotifications: properties: @@ -304,6 +339,8 @@ definitions: description: When this notification is marked as read, this will be updated with the current timestamp. type: string + web.CRUDable: {} + web.Rights: {} type: object models.Label: properties: @@ -312,8 +349,7 @@ definitions: value. type: string created_by: - allOf: - - $ref: '#/definitions/user.User' + $ref: '#/definitions/user.User' description: The user who created this label description: description: The label description. @@ -335,6 +371,8 @@ definitions: description: A timestamp when this label was last updated. You cannot change this value. type: string + web.CRUDable: {} + web.Rights: {} type: object models.LabelTask: properties: @@ -345,6 +383,8 @@ definitions: label_id: description: The label id you want to associate with a task. type: integer + web.CRUDable: {} + web.Rights: {} type: object models.LabelTaskBulk: properties: @@ -353,6 +393,8 @@ definitions: items: $ref: '#/definitions/models.Label' type: array + web.CRUDable: {} + web.Rights: {} type: object models.LinkSharing: properties: @@ -375,27 +417,26 @@ definitions: it after the link share has been created. type: string right: - allOf: - - $ref: '#/definitions/models.Right' default: 0 description: The right this project is shared with. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details. maximum: 2 + type: integer shared_by: - allOf: - - $ref: '#/definitions/user.User' - description: The user who shared this project + $ref: '#/definitions/user.User' + description: The user who shared this list sharing_type: - allOf: - - $ref: '#/definitions/models.SharingType' default: 0 description: The kind of this link. 0 = undefined, 1 = without password, 2 = with password. maximum: 2 + type: integer updated: description: A timestamp when this share was last updated. You cannot change this value. type: string + web.CRUDable: {} + web.Rights: {} type: object models.Message: properties: @@ -450,18 +491,14 @@ definitions: to the api. type: boolean owner: - allOf: - - $ref: '#/definitions/user.User' - description: The user who created this project. - parent_project_id: - type: integer + $ref: '#/definitions/user.User' + description: The user who created this list. position: description: The position this project has when querying all projects. See the tasks.position property on how to use this. type: number subscription: - allOf: - - $ref: '#/definitions/models.Subscription' + $ref: '#/definitions/models.Subscription' description: |- The subscription status for the user reading this project. You can only read this property, use the subscription endpoints to modify it. Will only returned when retreiving one project. @@ -474,16 +511,89 @@ definitions: description: A timestamp when this project was last updated. You cannot change this value. type: string + web.CRUDable: {} + web.Rights: {} type: object - models.ProjectDuplicate: + models.ListDuplicate: properties: - duplicated_project: - allOf: - - $ref: '#/definitions/models.Project' - description: The copied project - parent_project_id: - description: The target parent project + list: + $ref: '#/definitions/models.List' + description: The copied list + namespace_id: + description: The target namespace ID type: integer + web.CRUDable: {} + web.Rights: {} + type: object + models.ListUser: + properties: + created: + description: A timestamp when this relation was created. You cannot change + this value. + type: string + id: + description: The unique, numeric id of this list <-> user relation. + type: integer + right: + default: 0 + description: The right this user has. 0 = Read only, 1 = Read & Write, 2 = + Admin. See the docs for more details. + maximum: 2 + type: integer + updated: + description: A timestamp when this relation was last updated. You cannot change + this value. + type: string + user_id: + description: The username. + type: string + web.CRUDable: {} + web.Rights: {} + type: object + models.Message: + properties: + message: + description: A standard message. + type: string + type: object + models.Namespace: + properties: + created: + description: A timestamp when this namespace was created. You cannot change + this value. + type: string + description: + description: The description of the namespace + type: string + hex_color: + description: The hex color of this namespace + maxLength: 6 + type: string + id: + description: The unique, numeric id of this namespace. + type: integer + is_archived: + description: Whether or not a namespace is archived. + type: boolean + owner: + $ref: '#/definitions/user.User' + description: The user who owns this namespace + subscription: + $ref: '#/definitions/models.Subscription' + description: |- + The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it. + Will only returned when retreiving one namespace. + title: + description: The name of this namespace. + maxLength: 250 + minLength: 1 + type: string + updated: + description: A timestamp when this namespace was last updated. You cannot + change this value. + type: string + web.CRUDable: {} + web.Rights: {} type: object models.ProjectUser: properties: @@ -495,12 +605,11 @@ definitions: description: The unique, numeric id of this project <-> user relation. type: integer right: - allOf: - - $ref: '#/definitions/models.Right' default: 0 description: The right this user has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details. maximum: 2 + type: integer updated: description: A timestamp when this relation was last updated. You cannot change this value. @@ -508,6 +617,51 @@ definitions: user_id: description: The username. type: string + web.CRUDable: {} + web.Rights: {} + type: object + models.NamespaceWithLists: + properties: + created: + description: A timestamp when this namespace was created. You cannot change + this value. + type: string + description: + description: The description of the namespace + type: string + hex_color: + description: The hex color of this namespace + maxLength: 6 + type: string + id: + description: The unique, numeric id of this namespace. + type: integer + is_archived: + description: Whether or not a namespace is archived. + type: boolean + lists: + items: + $ref: '#/definitions/models.List' + type: array + owner: + $ref: '#/definitions/user.User' + description: The user who owns this namespace + subscription: + $ref: '#/definitions/models.Subscription' + description: |- + The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it. + Will only returned when retreiving one namespace. + title: + description: The name of this namespace. + maxLength: 250 + minLength: 1 + type: string + updated: + description: A timestamp when this namespace was last updated. You cannot + change this value. + type: string + web.CRUDable: {} + web.Rights: {} type: object models.RelatedTaskMap: additionalProperties: @@ -515,61 +669,6 @@ definitions: $ref: '#/definitions/models.Task' type: array type: object - models.RelationKind: - enum: - - unknown - - subtask - - parenttask - - related - - duplicateof - - duplicates - - blocking - - blocked - - precedes - - follows - - copiedfrom - - copiedto - type: string - x-enum-varnames: - - RelationKindUnknown - - RelationKindSubtask - - RelationKindParenttask - - RelationKindRelated - - RelationKindDuplicateOf - - RelationKindDuplicates - - RelationKindBlocking - - RelationKindBlocked - - RelationKindPreceeds - - RelationKindFollows - - RelationKindCopiedFrom - - RelationKindCopiedTo - models.ReminderRelation: - enum: - - due_date - - start_date - - end_date - type: string - x-enum-varnames: - - ReminderRelationDueDate - - ReminderRelationStartDate - - ReminderRelationEndDate - models.Right: - enum: - - 0 - - 1 - - 2 - type: integer - x-enum-varnames: - - RightRead - - RightWrite - - RightAdmin - models.RouteDetail: - properties: - method: - type: string - path: - type: string - type: object models.SavedFilter: properties: created: @@ -580,8 +679,7 @@ definitions: description: The description of the filter type: string filters: - allOf: - - $ref: '#/definitions/models.TaskCollection' + $ref: '#/definitions/models.TaskCollection' description: The actual filters this filter contains id: description: The unique numeric id of this saved filter @@ -591,8 +689,7 @@ definitions: a separate parent project together with favorite projects. type: boolean owner: - allOf: - - $ref: '#/definitions/user.User' + $ref: '#/definitions/user.User' description: The user who owns this filter title: description: The title of the filter. @@ -603,17 +700,9 @@ definitions: description: A timestamp when this filter was last updated. You cannot change this value. type: string + web.CRUDable: {} + web.Rights: {} type: object - models.SharingType: - enum: - - 0 - - 1 - - 2 - type: integer - x-enum-varnames: - - SharingTypeUnknown - - SharingTypeWithoutPassword - - SharingTypeWithPassword models.Subscription: properties: created: @@ -629,9 +718,10 @@ definitions: description: The numeric ID of the subscription type: integer user: - allOf: - - $ref: '#/definitions/user.User' + $ref: '#/definitions/user.User' description: The user who made this subscription + web.CRUDable: {} + web.Rights: {} type: object models.Task: properties: @@ -657,8 +747,7 @@ definitions: value. type: string created_by: - allOf: - - $ref: '#/definitions/user.User' + $ref: '#/definitions/user.User' description: The user who initially created the task. description: description: The task description. @@ -723,8 +812,7 @@ definitions: description: The project this task belongs to. type: integer related_tasks: - allOf: - - $ref: '#/definitions/models.RelatedTaskMap' + $ref: '#/definitions/models.RelatedTaskMap' description: All related tasks, grouped by their relation kind reminders: description: An array of reminders that are associated with this task. @@ -737,18 +825,16 @@ definitions: increase all remindes and the due date by its amount. type: integer repeat_mode: - allOf: - - $ref: '#/definitions/models.TaskRepeatMode' description: 'Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.' + type: integer start_date: description: When this task starts. type: string subscription: - allOf: - - $ref: '#/definitions/models.Subscription' + $ref: '#/definitions/models.Subscription' description: |- The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it. Will only returned when retrieving one task. @@ -760,6 +846,8 @@ definitions: description: A timestamp when this task was last updated. You cannot change this value. type: string + web.CRUDable: {} + web.Rights: {} type: object models.TaskAssginee: properties: @@ -767,6 +855,8 @@ definitions: type: string user_id: type: integer + web.CRUDable: {} + web.Rights: {} type: object models.TaskAttachment: properties: @@ -780,6 +870,8 @@ definitions: type: integer task_id: type: integer + web.CRUDable: {} + web.Rights: {} type: object models.TaskCollection: properties: @@ -817,6 +909,8 @@ definitions: items: type: string type: array + web.CRUDable: {} + web.Rights: {} type: object models.TaskComment: properties: @@ -830,6 +924,8 @@ definitions: type: integer updated: type: string + web.CRUDable: {} + web.Rights: {} type: object models.TaskRelation: properties: @@ -838,46 +934,20 @@ definitions: value. type: string created_by: - allOf: - - $ref: '#/definitions/user.User' + $ref: '#/definitions/user.User' description: The user who created this relation other_task_id: description: The ID of the other task, the task which is being related. type: integer relation_kind: - allOf: - - $ref: '#/definitions/models.RelationKind' description: The kind of the relation. + type: string task_id: description: The ID of the "base" task, the task which has a relation to another. type: integer + web.CRUDable: {} + web.Rights: {} type: object - models.TaskReminder: - properties: - relative_period: - description: 'A period in seconds relative to another date argument. Negative - values mean the reminder triggers before the date. Default: 0, tiggers when - RelativeTo is due.' - type: integer - relative_to: - allOf: - - $ref: '#/definitions/models.ReminderRelation' - description: The name of the date field to which the relative period refers - to. - reminder: - description: The absolute time when the user wants to be reminded of the task. - type: string - type: object - models.TaskRepeatMode: - enum: - - 0 - - 1 - - 2 - type: integer - x-enum-varnames: - - TaskRepeatModeDefault - - TaskRepeatModeMonth - - TaskRepeatModeFromCurrentDate models.Team: properties: created: @@ -885,8 +955,7 @@ definitions: this value. type: string created_by: - allOf: - - $ref: '#/definitions/user.User' + $ref: '#/definitions/user.User' description: The user who created this team. description: description: The team's description. @@ -912,6 +981,33 @@ definitions: description: A timestamp when this relation was last updated. You cannot change this value. type: string + web.CRUDable: {} + web.Rights: {} + type: object + models.TeamList: + properties: + created: + description: A timestamp when this relation was created. You cannot change + this value. + type: string + id: + description: The unique, numeric id of this list <-> team relation. + type: integer + right: + default: 0 + description: The right this team has. 0 = Read only, 1 = Read & Write, 2 = + Admin. See the docs for more details. + maximum: 2 + type: integer + team_id: + description: The team id. + type: integer + updated: + description: A timestamp when this relation was last updated. You cannot change + this value. + type: string + web.CRUDable: {} + web.Rights: {} type: object models.TeamMember: properties: @@ -930,6 +1026,8 @@ definitions: description: The username of the member. We use this to prevent automated user id entering. type: string + web.CRUDable: {} + web.Rights: {} type: object models.TeamProject: properties: @@ -941,12 +1039,11 @@ definitions: description: The unique, numeric id of this project <-> team relation. type: integer right: - allOf: - - $ref: '#/definitions/models.Right' default: 0 description: The right this team has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details. maximum: 2 + type: integer team_id: description: The team id. type: integer @@ -954,6 +1051,8 @@ definitions: description: A timestamp when this relation was last updated. You cannot change this value. type: string + web.CRUDable: {} + web.Rights: {} type: object models.TeamUser: properties: @@ -984,6 +1083,7 @@ definitions: maxLength: 250 minLength: 1 type: string + web.Auth: {} type: object models.TeamWithRight: properties: @@ -992,8 +1092,7 @@ definitions: this value. type: string created_by: - allOf: - - $ref: '#/definitions/user.User' + $ref: '#/definitions/user.User' description: The user who created this team. description: description: The team's description. @@ -1016,11 +1115,16 @@ definitions: maxLength: 250 type: string right: - $ref: '#/definitions/models.Right' + default: 0 + description: The right this team has. 0 = Read only, 1 = Read & Write, 2 = + Admin. See the docs for more details. + type: integer updated: description: A timestamp when this relation was last updated. You cannot change this value. type: string + web.CRUDable: {} + web.Rights: {} type: object models.UserWithRight: properties: @@ -1039,7 +1143,10 @@ definitions: description: The full name of the user. type: string right: - $ref: '#/definitions/models.Right' + default: 0 + description: The right this user has. 0 = Read only, 1 = Read & Write, 2 = + Admin. See the docs for more details. + type: integer updated: description: A timestamp when this task was last updated. You cannot change this value. @@ -1049,6 +1156,7 @@ definitions: maxLength: 250 minLength: 1 type: string + web.Auth: {} type: object models.Webhook: properties: @@ -1256,6 +1364,7 @@ definitions: maxLength: 250 minLength: 1 type: string + web.Auth: {} type: object v1.LinkShareAuth: properties: -- 2.45.1 From 23bbc97230b757cdfd85d023988e939ca05833ef Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 16:14:03 +0100 Subject: [PATCH 49/93] add errors to error doc, rewrite error messages specify error on teams model, add more declarative error specify error message on ErrOIDCTeamDoesNotExist --- docs/content/doc/usage/errors.md | 13 +++++++++++ pkg/models/error.go | 40 +++++++++++++++++++++++++------- pkg/models/teams.go | 2 +- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/docs/content/doc/usage/errors.md b/docs/content/doc/usage/errors.md index 605cdf364..94a0247dc 100644 --- a/docs/content/doc/usage/errors.md +++ b/docs/content/doc/usage/errors.md @@ -111,6 +111,19 @@ This document describes the different errors Vikunja can return. | 6010 | 400 | There are no oidc teams found for the user. | +| ErrorCode | HTTP Status Code | Description | +|-----------|------------------|-------------| +| 6001 | 400 | The team name cannot be emtpy. | +| 6002 | 404 | The team does not exist. | +| 6004 | 409 | The team already has access to that namespace or list. | +| 6005 | 409 | The user is already a member of that team. | +| 6006 | 400 | Cannot delete the last team member. | +| 6007 | 403 | The team does not have access to the list to perform that action. | +| 6008 | 400 | There are no teams found with that team name | +| 6009 | 400 | There is no oidc team with that team name and oidcId | +| 6010 | 400 | There are no oidc teams found for the user | + + ## User Project Access diff --git a/pkg/models/error.go b/pkg/models/error.go index e17e0b240..ece85d6bb 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1229,22 +1229,46 @@ type ErrTeamsDoNotExist struct { Name string } -// IsErrTeamDoNotExist checks if an error is ErrTeamDoesNotExist. +// IsErrTeamsDoNotExist checks if an error is ErrTeamsDoNotExist. func IsErrTeamsDoNotExist(err error) bool { _, ok := err.(ErrTeamsDoNotExist) return ok } func (err ErrTeamsDoNotExist) Error() string { - return fmt.Sprintf("Team does not exist [Team Name: %v]", err.Name) + return fmt.Sprintf("No teams with that name exist [Team Name: %v]", err.Name) } -// ErrCodeTeamDoesNotExist holds the unique world-error code of this error +// ErrCodeTeamsDoesNotExist holds the unique world-error code of this error const ErrCodeTeamsDoNotExist = 6008 // HTTPError holds the http error description func (err ErrTeamsDoNotExist) HTTPError() web.HTTPError { - return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No team with given name exists."} + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No teams with that name exist"} +} + +// ErrOIDCTeamDoesNotExist represents an error where a team with specified name and specified oidcId property does not exist +type ErrOIDCTeamDoesNotExist struct { + OidcId string + Name string +} + +// IsErrOIDCTeamDoesNotExist checks if an error is ErrOIDCTeamDoesNotExist. +func IsErrOIDCTeamDoesNotExist(err error) bool { + _, ok := err.(ErrOIDCTeamDoesNotExist) + return ok +} + +func (err ErrOIDCTeamDoesNotExist) Error() string { + return fmt.Sprintf("No Team with that name and valid property oidcId could be found [Team Name: %v] [OidcId : %v] ", err.Name, err.OidcId) +} + +// ErrCodeTeamDoesNotExist holds the unique world-error code of this error +const ErrCodeOIDCTeamDoesNotExist = 6009 + +// HTTPError holds the http error description +func (err ErrOIDCTeamDoesNotExist) HTTPError() web.HTTPError { + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Team with that name and valid property oidcId could be found."} } // ErrOIDCTeamsDoNotExistForUser represents an error where an oidcTeam does not exist for the user @@ -1254,20 +1278,20 @@ type ErrOIDCTeamsDoNotExistForUser struct { // IsErrOIDCTeamsDoNotExistForUser checks if an error is ErrOIDCTeamsDoNotExistForUser. func IsErrOIDCTeamsDoNotExistForUser(err error) bool { - _, ok := err.(ErrTeamDoesNotExist) + _, ok := err.(ErrOIDCTeamsDoNotExistForUser) return ok } func (err ErrOIDCTeamsDoNotExistForUser) Error() string { - return fmt.Sprintf("No Oidc exists for User [User ID: %d]", err.UserID) + return fmt.Sprintf("No Teams with property oidcId could be found for User [User ID: %d]", err.UserID) } // ErrCodeTeamDoesNotExist holds the unique world-error code of this error -const ErrCodeOIDCTeamsDoNotExistForUser = 6009 +const ErrCodeOIDCTeamsDoNotExistForUser = 6010 // HTTPError holds the http error description func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError { - return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "This team does not exist."} + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Teams with property oidcId could be found for User."} } // ==================== diff --git a/pkg/models/teams.go b/pkg/models/teams.go index b9450cef6..d91379784 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -159,7 +159,7 @@ func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (te if exists && err == nil { return team, nil } - return team, ErrTeamsDoNotExist{oidcID} + return team, ErrOIDCTeamDoesNotExist{teamName, oidcID} } func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err error) { -- 2.45.1 From 696cc951fa05d934008ead9ea2d15675c67aba23 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 17:24:42 +0100 Subject: [PATCH 50/93] remove manage admin function, nullcheck for oidc_id, undo removal of * in method TableName --- pkg/models/teams.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/pkg/models/teams.go b/pkg/models/teams.go index d91379784..9223c6d53 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -82,7 +82,7 @@ type TeamMember struct { } // TableName makes beautiful table names -func (TeamMember) TableName() string { +func (*TeamMember) TableName() string { return "team_members" } @@ -167,7 +167,7 @@ func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err e Table("team_members"). Where("user_id = ? ", userID). Join("RIGHT", "teams", "teams.id = team_members.team_id"). - Where("teams.oidc_id != ?", ""). + Where("teams.oidc_id != ? AND teams.oidc_id IS NOT NULL", ""). Cols("teams.id"). Find(&ts) if ts == nil || err != nil { @@ -366,11 +366,6 @@ func (t *Team) Create(s *xorm.Session, a web.Auth) (err error) { }) } -func (t *Team) ManageAdminRight(teamMember TeamMember, admin bool) { - // Insert the current user as member and admin - teamMember.Admin = admin -} - // Delete deletes a team // @Summary Deletes a team // @Description Delets a team. This will also remove the access for all users in that team. -- 2.45.1 From 6f2cd6c99ae2c5f094fa99fd7b13152cc5a85f2c Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 17:26:22 +0100 Subject: [PATCH 51/93] use models.TeamData instead of declaring struct twice --- pkg/modules/auth/openid/openid.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 50db45436..9490c18ea 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -59,11 +59,6 @@ type Provider struct { openIDProvider *oidc.Provider Oauth2Config *oauth2.Config `json:"-"` } -type TeamData struct { - TeamName string - OidcID string - Description string -} type claims struct { Email string `json:"email"` Name string `json:"name"` -- 2.45.1 From 105df8588e87eb58e698869f183800fe83e9d33c Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 19:52:18 +0100 Subject: [PATCH 52/93] rework openid.go, add errors to return, make team deletion more robust --- pkg/models/team_members.go | 9 +++++++ pkg/modules/auth/openid/openid.go | 41 ++++++++++--------------------- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index 9bcd06426..2e3285ff7 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -115,6 +115,15 @@ func (tm *TeamMember) CheckMembership(s *xorm.Session) (exists bool, err error) return exists, err } +func (tm *TeamMember) GetMemberCount(s *xorm.Session) (memberCount int, err error) { + members := []TeamMember{} + err = s. + Where("team_id = ?", tm.TeamID). + Cols("user_id"). + Find(&members) + return len(members), err +} + // Update toggles a team member's admin status // @Summary Toggle a team member's admin status // @Description If a user is team admin, this will make them member and vise-versa. diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 9490c18ea..388bb039e 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -195,7 +195,6 @@ func HandleCallback(c echo.Context) error { // Check if we have seen this user before u, err := getOrCreateUser(s, cl, idToken.Issuer, idToken.Subject) - if err != nil { _ = s.Rollback() log.Errorf("Error creating new user for provider %s: %v", provider.Name, err) @@ -203,14 +202,18 @@ func HandleCallback(c echo.Context) error { } // does the oidc token contain well formed "vikunja_groups" through vikunja_scope - teamData, err := getTeamDataFromToken(cl.VikunjaGroups, provider) - if err != nil { - log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) - return handler.HandleHTTPError(err, c) + teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, provider) + if len(errs) > 0 { + for _, err := range errs { + log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) + } } //find old teams for user through oidc - oldOidcTeams, _ := models.FindAllOidcTeamIDsForUser(s, u.ID) + oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) + if err != nil { + log.Errorf("No Oidc Teams found for user", err) + } var oidcTeams []int64 if len(teamData) > 0 { // check if we have seen these teams before. @@ -236,7 +239,10 @@ func HandleCallback(c echo.Context) error { log.Errorf("Found Error while signing out from teams %v", err) } } - SignOutFromOrDeleteTeamsByID(s, u, notIn(oldOidcTeams, oidcTeams)) + errs = SignOutFromOrDeleteTeamsByID(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + for _, err := range errs { + log.Errorf("Found Error while signing out from teams %v", err) + } err = s.Commit() if err != nil { _ = s.Rollback() @@ -358,7 +364,6 @@ func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.OIDCTeamD } } - log.Debugf("Array: %v", te) return te, err } @@ -429,23 +434,3 @@ func getOrCreateUser(s *xorm.Session, cl *claims, issuer, subject string) (u *us return } - -// find the elements which appear in slice1,but not in slice2 -func notIn(slice1 []int64, slice2 []int64) []int64 { - var diff []int64 - - for _, s1 := range slice1 { - found := false - for _, s2 := range slice2 { - if s1 == s2 { - found = true - break - } - } - // String not found. We add it to return slice - if !found { - diff = append(diff, s1) - } - } - return diff -} -- 2.45.1 From 7f9c48c87ad80bc88b090f23708bdbab5a3eb98e Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 20:04:25 +0100 Subject: [PATCH 53/93] make documentation cleaner --- pkg/modules/auth/openid/openid.md | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/pkg/modules/auth/openid/openid.md b/pkg/modules/auth/openid/openid.md index 94399e5fe..864b66614 100644 --- a/pkg/modules/auth/openid/openid.md +++ b/pkg/modules/auth/openid/openid.md @@ -1,14 +1,12 @@ -regarding: -https://kolaente.dev/vikunja/api/pulls/1279 - # Assign teams via oidc This PR adds the functionality to assign users to teams via oidc. Read carefully and brief your administrators to use this feature. Tested with oidc provider authentik. -To distinguish between groups created in vikunja and groups generated via oidc, there is an attribute neccessary, which is called: *oidcID* +To distinguish between teams created in vikunja and teams generated via oidc, an attribute for vikunja teams is introduced, which is called: *oidcID* ## Setup -Edit config.yml to include scope: openid profile email vikunja_scope + +Edit [config.yml](https://kolaente.dev/vikunja/api/src/branch/main/config.yml.sample) to include scope: openid profile email vikunja_scope For authentik to use group assignment feature: - go to: .../if/admin/#/core/property-mappings @@ -50,24 +48,6 @@ You should see "the description you entered in the oidc provider's admin area" - You will see "(sso: XXXXX)" written next to each team you were asigned through oidc. -## IMPORTANT NOTES: -<<<<<<< HEAD -* **SSO/OIDC teams cannot be edited.** - -* **It is crucial to call the element "vikunja_groups" since this is the name vikunja is looking for.** - -* **Additionally, make sure to deliver an "oidcID" and a "name".** -======= -**SSO/OIDC teams cannot be edited.** - -**It is crucial to call the element "vikunja_groups" since this is the name vikunja is looking for.** - -**Additionally, make sure to deliver an "oidcID" and a "name".** - ->>>>>>> 8d46490d... add openid.md as readme for feature: 950 assigning group through oidc claim - - - ____________________________________________________________________________ ## BEHAVIOR -- 2.45.1 From 60bd4611b2ec0402bce9a21214ce19ca753a0b17 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 13 Feb 2023 20:43:24 +0100 Subject: [PATCH 54/93] fix lint --- pkg/models/error.go | 4 +-- pkg/modules/auth/openid/openid.go | 49 ++++++++++++++++--------------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/pkg/models/error.go b/pkg/models/error.go index ece85d6bb..6b0b28c0e 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1249,7 +1249,7 @@ func (err ErrTeamsDoNotExist) HTTPError() web.HTTPError { // ErrOIDCTeamDoesNotExist represents an error where a team with specified name and specified oidcId property does not exist type ErrOIDCTeamDoesNotExist struct { - OidcId string + OidcID string Name string } @@ -1260,7 +1260,7 @@ func IsErrOIDCTeamDoesNotExist(err error) bool { } func (err ErrOIDCTeamDoesNotExist) Error() string { - return fmt.Sprintf("No Team with that name and valid property oidcId could be found [Team Name: %v] [OidcId : %v] ", err.Name, err.OidcId) + return fmt.Sprintf("No Team with that name and valid property oidcId could be found [Team Name: %v] [OidcId : %v] ", err.Name, err.OidcID) } // ErrCodeTeamDoesNotExist holds the unique world-error code of this error diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 388bb039e..b436f83d7 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -203,26 +203,41 @@ func HandleCallback(c echo.Context) error { // does the oidc token contain well formed "vikunja_groups" through vikunja_scope teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, provider) - if len(errs) > 0 { - for _, err := range errs { - log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) - } + for _, err := range errs { + log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) } //find old teams for user through oidc oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) if err != nil { - log.Errorf("No Oidc Teams found for user", err) + log.Errorf("No Oidc Teams found for user %v", err) } - var oidcTeams []int64 + oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) + if err != nil { + log.Errorf("Could not proceed with group routine %v", err) + } + errs = SignOutFromOrDeleteTeamsByID(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + for _, err := range errs { + log.Errorf("Found Error while signing out from teams %v", err) + } + err = s.Commit() + if err != nil { + _ = s.Rollback() + log.Errorf("Error creating new Team for provider %s: %v", provider.Name, err) + return handler.HandleHTTPError(err, c) + } + // Create token + return auth.NewUserAuthTokenResponse(u, c, false) +} + +func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.TeamData) (oidcTeams []int64, err error) { if len(teamData) > 0 { // check if we have seen these teams before. // find or create Teams and assign user as teammember. - log.Debugf("TeamData is set %v", teamData) teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u) if err != nil { - log.Errorf("Error verifying team for name %v, got %v", cl.Name, teams, err) - return err + log.Errorf("Error verifying team for %v, got %v. Error: %v", u.Name, teams, err) + return nil, err } //find old teams for user through oidc @@ -239,19 +254,7 @@ func HandleCallback(c echo.Context) error { log.Errorf("Found Error while signing out from teams %v", err) } } - errs = SignOutFromOrDeleteTeamsByID(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) - for _, err := range errs { - log.Errorf("Found Error while signing out from teams %v", err) - } - err = s.Commit() - if err != nil { - _ = s.Rollback() - log.Errorf("Error creating new Team for provider %s: %v", provider.Name, err) - return handler.HandleHTTPError(err, c) - } - // Create token - return auth.NewUserAuthTokenResponse(u, c, false) -} + return oidcTeams, err func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.OIDCTeamData) (oidcTeams []int64, err error) { if len(teamData) == 0 { @@ -290,7 +293,7 @@ func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (e if !exists { continue } - err = tm.Delete(s, u) + err := tm.Delete(s, u) // if you cannot delete the team_member if err != nil { errs = append(errs, err) -- 2.45.1 From 6bd5efa00b1fbaa62061ff6f41e424ab341c6bea Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 23 Feb 2023 15:23:32 +0100 Subject: [PATCH 55/93] undo team gets deleted if user is last team member remove logic behind deleting last team_member --- pkg/models/team_members.go | 10 +++++----- pkg/modules/auth/openid/openid.go | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index 2e3285ff7..edc9632df 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -115,13 +115,13 @@ func (tm *TeamMember) CheckMembership(s *xorm.Session) (exists bool, err error) return exists, err } -func (tm *TeamMember) GetMemberCount(s *xorm.Session) (memberCount int, err error) { - members := []TeamMember{} - err = s. +func (tm *TeamMember) GetMemberCount(s *xorm.Session) (memberCount int64, err error) { + member := TeamMember{} + memberCount, err = s. Where("team_id = ?", tm.TeamID). Cols("user_id"). - Find(&members) - return len(members), err + Count(&member) + return memberCount, err } // Update toggles a team member's admin status diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index b436f83d7..c88700fc2 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -216,7 +216,8 @@ func HandleCallback(c echo.Context) error { if err != nil { log.Errorf("Could not proceed with group routine %v", err) } - errs = SignOutFromOrDeleteTeamsByID(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + errs = SignOutFromTeamsByID(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + log.Errorf("%v", errs) for _, err := range errs { log.Errorf("Found Error while signing out from teams %v", err) } @@ -293,7 +294,7 @@ func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (e if !exists { continue } - err := tm.Delete(s, u) + err = tm.Delete(s, u) // if you cannot delete the team_member if err != nil { errs = append(errs, err) -- 2.45.1 From 8045d68c2ebbdc19095c10686e53db73122c3f5a Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 23 Feb 2023 15:52:16 +0100 Subject: [PATCH 56/93] add punctuation and comments for errors --- docs/content/doc/usage/errors.md | 6 +++--- pkg/models/error.go | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/content/doc/usage/errors.md b/docs/content/doc/usage/errors.md index 94a0247dc..85bc5722e 100644 --- a/docs/content/doc/usage/errors.md +++ b/docs/content/doc/usage/errors.md @@ -119,9 +119,9 @@ This document describes the different errors Vikunja can return. | 6005 | 409 | The user is already a member of that team. | | 6006 | 400 | Cannot delete the last team member. | | 6007 | 403 | The team does not have access to the list to perform that action. | -| 6008 | 400 | There are no teams found with that team name | -| 6009 | 400 | There is no oidc team with that team name and oidcId | -| 6010 | 400 | There are no oidc teams found for the user | +| 6008 | 400 | There are no teams found with that team name. | +| 6009 | 400 | There is no oidc team with that team name and oidcId. | +| 6010 | 400 | There are no oidc teams found for the user. | diff --git a/pkg/models/error.go b/pkg/models/error.go index 6b0b28c0e..eda0c56cd 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1225,6 +1225,7 @@ func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Teams with property oidcId could be found for User."} } +// ErrTeamsDoNotExist represents an error where Teams searched via non-unique name do not exist. type ErrTeamsDoNotExist struct { Name string } @@ -1259,6 +1260,7 @@ func IsErrOIDCTeamDoesNotExist(err error) bool { return ok } +// ErrTeamDoesNotExist represents an error where a team does not exist func (err ErrOIDCTeamDoesNotExist) Error() string { return fmt.Sprintf("No Team with that name and valid property oidcId could be found [Team Name: %v] [OidcId : %v] ", err.Name, err.OidcID) } -- 2.45.1 From 3a3aa57ca4f19069d6fef76cc897d9f56e1bd5bd Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 23 Feb 2023 16:17:59 +0100 Subject: [PATCH 57/93] cast VikunjaGroups directly to []map[string]interface{} changing []models.Team to []*models.Team --- pkg/modules/auth/openid/openid.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index c88700fc2..0c2f601b8 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -366,7 +366,6 @@ func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.OIDCTeamD log.Debugf("Team with oidc_id %v and name %v already exists.", team.OidcID, team.Name) te = append(te, &team) } - } return te, err } -- 2.45.1 From bf87763b2f106bb9eb68f1afbb665a007d144b22 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 23 Feb 2023 16:32:20 +0100 Subject: [PATCH 58/93] change generic name TeamData struct to OIDCTeamData --- pkg/modules/auth/openid/openid.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 0c2f601b8..60732c6bf 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -231,7 +231,7 @@ func HandleCallback(c echo.Context) error { return auth.NewUserAuthTokenResponse(u, c, false) } -func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.TeamData) (oidcTeams []int64, err error) { +func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.OIDCTeamData) (oidcTeams []int64, err error) { if len(teamData) > 0 { // check if we have seen these teams before. // find or create Teams and assign user as teammember. @@ -340,7 +340,11 @@ func getTeamDataFromToken(groups []map[string]interface{}, provider *Provider) ( } func CreateTeamWithData(s *xorm.Session, teamData models.OIDCTeamData, u *user.User) (team *models.Team, err error) { +<<<<<<< HEAD team = &models.Team{ +======= + tea := &models.Team{ +>>>>>>> b607fea4... change too generic name TeamData struct to OIDCTeamData Name: teamData.TeamName, Description: teamData.Description, OidcID: teamData.OidcID, -- 2.45.1 From 47801df9741a73ee7fad13224918cd0733ac728d Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 10 Mar 2023 13:46:18 +0100 Subject: [PATCH 59/93] remove left over function GetMemberCount, rename function SignOut to RemoveFrom --- pkg/models/team_members.go | 9 --------- pkg/modules/auth/openid/openid.go | 9 ++++----- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index edc9632df..9bcd06426 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -115,15 +115,6 @@ func (tm *TeamMember) CheckMembership(s *xorm.Session) (exists bool, err error) return exists, err } -func (tm *TeamMember) GetMemberCount(s *xorm.Session) (memberCount int64, err error) { - member := TeamMember{} - memberCount, err = s. - Where("team_id = ?", tm.TeamID). - Cols("user_id"). - Count(&member) - return memberCount, err -} - // Update toggles a team member's admin status // @Summary Toggle a team member's admin status // @Description If a user is team admin, this will make them member and vise-versa. diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 60732c6bf..adbdaaa8b 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -216,7 +216,7 @@ func HandleCallback(c echo.Context) error { if err != nil { log.Errorf("Could not proceed with group routine %v", err) } - errs = SignOutFromTeamsByID(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + errs = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) log.Errorf("%v", errs) for _, err := range errs { log.Errorf("Found Error while signing out from teams %v", err) @@ -281,7 +281,10 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models. } return oidcTeams, err } +<<<<<<< HEAD +======= +>>>>>>> 169b668c... remove left over function GetMemberCount, rename function SignOut to RemoveFrom func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (errs []error) { errs = []error{} for _, teamID := range teamIDs { @@ -340,11 +343,7 @@ func getTeamDataFromToken(groups []map[string]interface{}, provider *Provider) ( } func CreateTeamWithData(s *xorm.Session, teamData models.OIDCTeamData, u *user.User) (team *models.Team, err error) { -<<<<<<< HEAD team = &models.Team{ -======= - tea := &models.Team{ ->>>>>>> b607fea4... change too generic name TeamData struct to OIDCTeamData Name: teamData.TeamName, Description: teamData.Description, OidcID: teamData.OidcID, -- 2.45.1 From ffeae4065ccd8284f46dd58240c577aaa4acb378 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 30 Mar 2023 17:15:07 +0200 Subject: [PATCH 60/93] add swagger files --- pkg/swagger/docs.go | 396 +++++++++++++++++++++-------------- pkg/swagger/swagger.json | 436 +++++++++++++++++++++++---------------- pkg/swagger/swagger.yaml | 252 +++++++++++----------- 3 files changed, 630 insertions(+), 454 deletions(-) diff --git a/pkg/swagger/docs.go b/pkg/swagger/docs.go index 60e21cce5..64a6ee8e2 100644 --- a/pkg/swagger/docs.go +++ b/pkg/swagger/docs.go @@ -7272,36 +7272,11 @@ const docTemplate = `{ }, "created_by": { "description": "The user who initially created the bucket.", - "$ref": "#/definitions/user.User" - }, - "filter_by": { - "description": "The field name of the field to filter by", - "type": "array", - "items": { - "type": "string" - } - }, - "filter_comparator": { - "description": "The comparator for field and value", - "type": "array", - "items": { - "type": "string" - } - }, - "filter_concat": { - "description": "The way all filter conditions are concatenated together, can be either \"and\" or \"or\".,", - "type": "string" - }, - "filter_include_nulls": { - "description": "If set to true, the result will also include null values", - "type": "boolean" - }, - "filter_value": { - "description": "The value of the field name to filter by", - "type": "array", - "items": { - "type": "string" - } + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "id": { "description": "The unique, numeric id of this bucket.", @@ -7318,6 +7293,7 @@ const docTemplate = `{ "description": "The list this bucket belongs to.", "type": "integer" }, +<<<<<<< HEAD "order_by": { "description": "The query parameter to order the items by. This can be either asc or desc, with asc being the default.", "type": "array", @@ -7326,10 +7302,13 @@ const docTemplate = `{ } }, >>>>>>> 4567a680... do the swag +======= +>>>>>>> 85307ce6... add swagger files "position": { "description": "The position this bucket has when querying all buckets. See the tasks.position property on how to use this.", "type": "number" }, +<<<<<<< HEAD <<<<<<< HEAD "project_id": { "description": "The project this bucket belongs to.", @@ -7343,6 +7322,8 @@ const docTemplate = `{ } >>>>>>> 4567a680... do the swag }, +======= +>>>>>>> 85307ce6... add swagger files "tasks": { "description": "All tasks which belong to this bucket.", "type": "array", @@ -7358,9 +7339,7 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this bucket was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.BulkAssignees": { @@ -7372,9 +7351,7 @@ const docTemplate = `{ "items": { "$ref": "#/definitions/user.User" } - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.BulkTask": { @@ -7408,7 +7385,11 @@ const docTemplate = `{ }, "created_by": { "description": "The user who initially created the task.", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "description": { "description": "The task description.", @@ -7480,7 +7461,11 @@ const docTemplate = `{ }, "related_tasks": { "description": "All related tasks, grouped by their relation kind", - "$ref": "#/definitions/models.RelatedTaskMap" + "allOf": [ + { + "$ref": "#/definitions/models.RelatedTaskMap" + } + ] }, "reminders": { "description": "An array of reminders that are associated with this task.", @@ -7495,7 +7480,11 @@ const docTemplate = `{ }, "repeat_mode": { "description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.", - "type": "integer" + "allOf": [ + { + "$ref": "#/definitions/models.TaskRepeatMode" + } + ] }, "start_date": { "description": "When this task starts.", @@ -7511,8 +7500,16 @@ const docTemplate = `{ ] ======= "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.", +<<<<<<< HEAD "$ref": "#/definitions/models.Subscription" >>>>>>> 4567a680... do the swag +======= + "allOf": [ + { + "$ref": "#/definitions/models.Subscription" + } + ] +>>>>>>> 85307ce6... add swagger files }, "task_ids": { "description": "A project of task ids to update", @@ -7529,9 +7526,7 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this task was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.DatabaseNotifications": { @@ -7559,9 +7554,7 @@ const docTemplate = `{ "read_at": { "description": "When this notification is marked as read, this will be updated with the current timestamp.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.Label": { @@ -7573,7 +7566,11 @@ const docTemplate = `{ }, "created_by": { "description": "The user who created this label", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "description": { "description": "The label description.", @@ -7597,9 +7594,7 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this label was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.LabelTask": { @@ -7612,9 +7607,7 @@ const docTemplate = `{ "label_id": { "description": "The label id you want to associate with a task.", "type": "integer" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.LabelTaskBulk": { @@ -7626,9 +7619,7 @@ const docTemplate = `{ "items": { "$ref": "#/definitions/models.Label" } - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.LinkSharing": { @@ -7659,10 +7650,18 @@ const docTemplate = `{ "description": "The right this project is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", ======= "description": "The right this list is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", +<<<<<<< HEAD "type": "integer", >>>>>>> 4567a680... do the swag +======= +>>>>>>> 85307ce6... add swagger files "default": 0, - "maximum": 2 + "maximum": 2, + "allOf": [ + { + "$ref": "#/definitions/models.Right" + } + ] }, "shared_by": { <<<<<<< HEAD @@ -7674,21 +7673,31 @@ const docTemplate = `{ ] ======= "description": "The user who shared this list", +<<<<<<< HEAD "$ref": "#/definitions/user.User" >>>>>>> 4567a680... do the swag +======= + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] +>>>>>>> 85307ce6... add swagger files }, "sharing_type": { "description": "The kind of this link. 0 = undefined, 1 = without password, 2 = with password.", - "type": "integer", "default": 0, - "maximum": 2 + "maximum": 2, + "allOf": [ + { + "$ref": "#/definitions/models.SharingType" + } + ] }, "updated": { "description": "A timestamp when this share was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.Message": { @@ -7759,11 +7768,19 @@ const docTemplate = `{ ] ======= "description": "The user who created this list.", +<<<<<<< HEAD "$ref": "#/definitions/user.User" >>>>>>> 4567a680... do the swag }, "parent_project_id": { "type": "integer" +======= + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] +>>>>>>> 85307ce6... add swagger files }, "position": { "description": "The position this project has when querying all projects. See the tasks.position property on how to use this.", @@ -7779,8 +7796,16 @@ const docTemplate = `{ ] ======= "description": "The subscription status for the user reading this list. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one list.", +<<<<<<< HEAD "$ref": "#/definitions/models.Subscription" >>>>>>> 4567a680... do the swag +======= + "allOf": [ + { + "$ref": "#/definitions/models.Subscription" + } + ] +>>>>>>> 85307ce6... add swagger files }, "title": { "description": "The title of the project. You'll see this in the overview.", @@ -7791,9 +7816,7 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this project was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, <<<<<<< HEAD @@ -7818,14 +7841,16 @@ const docTemplate = `{ "properties": { "list": { "description": "The copied list", - "$ref": "#/definitions/models.List" + "allOf": [ + { + "$ref": "#/definitions/models.List" + } + ] }, "namespace_id": { "description": "The target namespace ID", "type": "integer" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.ListUser": { @@ -7841,9 +7866,13 @@ const docTemplate = `{ }, "right": { "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", "default": 0, - "maximum": 2 + "maximum": 2, + "allOf": [ + { + "$ref": "#/definitions/models.Right" + } + ] }, "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", @@ -7852,9 +7881,7 @@ const docTemplate = `{ "user_id": { "description": "The username.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.Message": { @@ -7892,11 +7919,19 @@ const docTemplate = `{ }, "owner": { "description": "The user who owns this namespace", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "subscription": { "description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.", - "$ref": "#/definitions/models.Subscription" + "allOf": [ + { + "$ref": "#/definitions/models.Subscription" + } + ] }, "title": { "description": "The name of this namespace.", @@ -7907,10 +7942,14 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this namespace was last updated. You cannot change this value.", "type": "string" +<<<<<<< HEAD }, "web.CRUDable": {}, "web.Rights": {} >>>>>>> 4567a680... do the swag +======= + } +>>>>>>> 85307ce6... add swagger files } }, "models.ProjectUser": { @@ -7926,9 +7965,13 @@ const docTemplate = `{ }, "right": { "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", "default": 0, - "maximum": 2 + "maximum": 2, + "allOf": [ + { + "$ref": "#/definitions/models.Right" + } + ] }, "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", @@ -7937,9 +7980,7 @@ const docTemplate = `{ "user_id": { "description": "The username.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, <<<<<<< HEAD @@ -7976,11 +8017,19 @@ const docTemplate = `{ }, "owner": { "description": "The user who owns this namespace", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "subscription": { "description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.", - "$ref": "#/definitions/models.Subscription" + "allOf": [ + { + "$ref": "#/definitions/models.Subscription" + } + ] }, "title": { "description": "The name of this namespace.", @@ -7991,9 +8040,7 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this namespace was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, >>>>>>> 4567a680... do the swag @@ -8007,6 +8054,9 @@ const docTemplate = `{ } }, <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 85307ce6... add swagger files "models.RelationKind": { "type": "string", "enum": [ @@ -8038,6 +8088,7 @@ const docTemplate = `{ "RelationKindCopiedTo" ] }, +<<<<<<< HEAD "models.ReminderRelation": { "type": "string", "enum": [ @@ -8051,6 +8102,8 @@ const docTemplate = `{ "ReminderRelationEndDate" ] }, +======= +>>>>>>> 85307ce6... add swagger files "models.Right": { "type": "integer", "enum": [ @@ -8064,6 +8117,7 @@ const docTemplate = `{ "RightAdmin" ] }, +<<<<<<< HEAD "models.RouteDetail": { "type": "object", "properties": { @@ -8077,6 +8131,8 @@ const docTemplate = `{ }, ======= >>>>>>> 4567a680... do the swag +======= +>>>>>>> 85307ce6... add swagger files "models.SavedFilter": { "type": "object", "properties": { @@ -8090,7 +8146,11 @@ const docTemplate = `{ }, "filters": { "description": "The actual filters this filter contains", - "$ref": "#/definitions/models.TaskCollection" + "allOf": [ + { + "$ref": "#/definitions/models.TaskCollection" + } + ] }, "id": { "description": "The unique numeric id of this saved filter", @@ -8102,7 +8162,11 @@ const docTemplate = `{ }, "owner": { "description": "The user who owns this filter", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "title": { "description": "The title of the filter.", @@ -8113,11 +8177,22 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this filter was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, + "models.SharingType": { + "type": "integer", + "enum": [ + 0, + 1, + 2 + ], + "x-enum-varnames": [ + "SharingTypeUnknown", + "SharingTypeWithoutPassword", + "SharingTypeWithPassword" + ] + }, "models.Subscription": { "type": "object", "properties": { @@ -8138,10 +8213,12 @@ const docTemplate = `{ }, "user": { "description": "The user who made this subscription", - "$ref": "#/definitions/user.User" - }, - "web.CRUDable": {}, - "web.Rights": {} + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] + } } }, "models.Task": { @@ -8175,7 +8252,11 @@ const docTemplate = `{ }, "created_by": { "description": "The user who initially created the task.", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "description": { "description": "The task description.", @@ -8247,7 +8328,11 @@ const docTemplate = `{ }, "related_tasks": { "description": "All related tasks, grouped by their relation kind", - "$ref": "#/definitions/models.RelatedTaskMap" + "allOf": [ + { + "$ref": "#/definitions/models.RelatedTaskMap" + } + ] }, "reminders": { "description": "An array of reminders that are associated with this task.", @@ -8262,7 +8347,11 @@ const docTemplate = `{ }, "repeat_mode": { "description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.", - "type": "integer" + "allOf": [ + { + "$ref": "#/definitions/models.TaskRepeatMode" + } + ] }, "start_date": { "description": "When this task starts.", @@ -8270,7 +8359,11 @@ const docTemplate = `{ }, "subscription": { "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.", - "$ref": "#/definitions/models.Subscription" + "allOf": [ + { + "$ref": "#/definitions/models.Subscription" + } + ] }, "title": { "description": "The task text. This is what you'll see in the project.", @@ -8280,9 +8373,7 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this task was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TaskAssginee": { @@ -8293,9 +8384,7 @@ const docTemplate = `{ }, "user_id": { "type": "integer" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TaskAttachment": { @@ -8315,9 +8404,7 @@ const docTemplate = `{ }, "task_id": { "type": "integer" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TaskCollection": { @@ -8365,9 +8452,7 @@ const docTemplate = `{ "items": { "type": "string" } - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TaskComment": { @@ -8387,9 +8472,7 @@ const docTemplate = `{ }, "updated": { "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TaskRelation": { @@ -8401,7 +8484,11 @@ const docTemplate = `{ }, "created_by": { "description": "The user who created this relation", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "other_task_id": { "description": "The ID of the other task, the task which is being related.", @@ -8409,16 +8496,19 @@ const docTemplate = `{ }, "relation_kind": { "description": "The kind of the relation.", - "type": "string" + "allOf": [ + { + "$ref": "#/definitions/models.RelationKind" + } + ] }, "task_id": { "description": "The ID of the \"base\" task, the task which has a relation to another.", "type": "integer" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, +<<<<<<< HEAD <<<<<<< HEAD "models.TaskReminder": { "type": "object", @@ -8441,6 +8531,8 @@ const docTemplate = `{ } } }, +======= +>>>>>>> 85307ce6... add swagger files "models.TaskRepeatMode": { "type": "integer", "enum": [ @@ -8454,8 +8546,11 @@ const docTemplate = `{ "TaskRepeatModeFromCurrentDate" ] }, +<<<<<<< HEAD ======= >>>>>>> 4567a680... do the swag +======= +>>>>>>> 85307ce6... add swagger files "models.Team": { "type": "object", "properties": { @@ -8465,7 +8560,11 @@ const docTemplate = `{ }, "created_by": { "description": "The user who created this team.", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "description": { "description": "The team's description.", @@ -8496,9 +8595,7 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, <<<<<<< HEAD @@ -8516,9 +8613,13 @@ const docTemplate = `{ }, "right": { "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", "default": 0, - "maximum": 2 + "maximum": 2, + "allOf": [ + { + "$ref": "#/definitions/models.Right" + } + ] }, "team_id": { "description": "The team id.", @@ -8527,9 +8628,7 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, >>>>>>> 4567a680... do the swag @@ -8551,9 +8650,7 @@ const docTemplate = `{ "username": { "description": "The username of the member. We use this to prevent automated user id entering.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TeamProject": { @@ -8569,9 +8666,13 @@ const docTemplate = `{ }, "right": { "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", "default": 0, - "maximum": 2 + "maximum": 2, + "allOf": [ + { + "$ref": "#/definitions/models.Right" + } + ] }, "team_id": { "description": "The team id.", @@ -8580,9 +8681,7 @@ const docTemplate = `{ "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TeamUser": { @@ -8618,8 +8717,7 @@ const docTemplate = `{ "type": "string", "maxLength": 250, "minLength": 1 - }, - "web.Auth": {} + } } }, "models.TeamWithRight": { @@ -8631,7 +8729,11 @@ const docTemplate = `{ }, "created_by": { "description": "The user who created this team.", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "description": { "description": "The team's description.", @@ -8660,16 +8762,12 @@ const docTemplate = `{ "maxLength": 250 }, "right": { - "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", - "default": 0 + "$ref": "#/definitions/models.Right" }, "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.UserWithRight": { @@ -8693,9 +8791,7 @@ const docTemplate = `{ "type": "string" }, "right": { - "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", - "default": 0 + "$ref": "#/definitions/models.Right" }, "updated": { "description": "A timestamp when this task was last updated. You cannot change this value.", @@ -8706,8 +8802,7 @@ const docTemplate = `{ "type": "string", "maxLength": 250, "minLength": 1 - }, - "web.Auth": {} + } } }, "models.Webhook": { @@ -8989,8 +9084,7 @@ const docTemplate = `{ "type": "string", "maxLength": 250, "minLength": 1 - }, - "web.Auth": {} + } } }, "v1.LinkShareAuth": { diff --git a/pkg/swagger/swagger.json b/pkg/swagger/swagger.json index a01eae950..f3ab167d3 100644 --- a/pkg/swagger/swagger.json +++ b/pkg/swagger/swagger.json @@ -7264,36 +7264,11 @@ }, "created_by": { "description": "The user who initially created the bucket.", - "$ref": "#/definitions/user.User" - }, - "filter_by": { - "description": "The field name of the field to filter by", - "type": "array", - "items": { - "type": "string" - } - }, - "filter_comparator": { - "description": "The comparator for field and value", - "type": "array", - "items": { - "type": "string" - } - }, - "filter_concat": { - "description": "The way all filter conditions are concatenated together, can be either \"and\" or \"or\".,", - "type": "string" - }, - "filter_include_nulls": { - "description": "If set to true, the result will also include null values", - "type": "boolean" - }, - "filter_value": { - "description": "The value of the field name to filter by", - "type": "array", - "items": { - "type": "string" - } + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "id": { "description": "The unique, numeric id of this bucket.", @@ -7308,24 +7283,10 @@ "description": "The list this bucket belongs to.", "type": "integer" }, - "order_by": { - "description": "The query parameter to order the items by. This can be either asc or desc, with asc being the default.", - "type": "array", - "items": { - "type": "string" - } - }, "position": { "description": "The position this bucket has when querying all buckets. See the tasks.position property on how to use this.", "type": "number" }, - "sort_by": { - "description": "The query parameter to sort by. This is for ex. done, priority, etc.", - "type": "array", - "items": { - "type": "string" - } - }, "tasks": { "description": "All tasks which belong to this bucket.", "type": "array", @@ -7341,9 +7302,7 @@ "updated": { "description": "A timestamp when this bucket was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.BulkAssignees": { @@ -7355,9 +7314,7 @@ "items": { "$ref": "#/definitions/user.User" } - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.BulkTask": { @@ -7391,7 +7348,11 @@ }, "created_by": { "description": "The user who initially created the task.", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "description": { "description": "The task description.", @@ -7463,7 +7424,11 @@ }, "related_tasks": { "description": "All related tasks, grouped by their relation kind", - "$ref": "#/definitions/models.RelatedTaskMap" + "allOf": [ + { + "$ref": "#/definitions/models.RelatedTaskMap" + } + ] }, "reminders": { "description": "An array of reminders that are associated with this task.", @@ -7478,7 +7443,11 @@ }, "repeat_mode": { "description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.", - "type": "integer" + "allOf": [ + { + "$ref": "#/definitions/models.TaskRepeatMode" + } + ] }, "start_date": { "description": "When this task starts.", @@ -7486,7 +7455,11 @@ }, "subscription": { "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.", - "$ref": "#/definitions/models.Subscription" + "allOf": [ + { + "$ref": "#/definitions/models.Subscription" + } + ] }, "task_ids": { "description": "A project of task ids to update", @@ -7503,9 +7476,7 @@ "updated": { "description": "A timestamp when this task was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.DatabaseNotifications": { @@ -7533,9 +7504,7 @@ "read_at": { "description": "When this notification is marked as read, this will be updated with the current timestamp.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.Label": { @@ -7547,7 +7516,11 @@ }, "created_by": { "description": "The user who created this label", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "description": { "description": "The label description.", @@ -7571,9 +7544,7 @@ "updated": { "description": "A timestamp when this label was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.LabelTask": { @@ -7586,9 +7557,7 @@ "label_id": { "description": "The label id you want to associate with a task.", "type": "integer" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.LabelTaskBulk": { @@ -7600,9 +7569,7 @@ "items": { "$ref": "#/definitions/models.Label" } - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.LinkSharing": { @@ -7630,26 +7597,36 @@ }, "right": { "description": "The right this list is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", "default": 0, - "maximum": 2 + "maximum": 2, + "allOf": [ + { + "$ref": "#/definitions/models.Right" + } + ] }, "shared_by": { "description": "The user who shared this list", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "sharing_type": { "description": "The kind of this link. 0 = undefined, 1 = without password, 2 = with password.", - "type": "integer", "default": 0, - "maximum": 2 + "maximum": 2, + "allOf": [ + { + "$ref": "#/definitions/models.SharingType" + } + ] }, "updated": { "description": "A timestamp when this share was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.Message": { @@ -7712,7 +7689,11 @@ }, "owner": { "description": "The user who created this list.", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "parent_project_id": { "type": "integer" @@ -7723,7 +7704,11 @@ }, "subscription": { "description": "The subscription status for the user reading this list. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one list.", - "$ref": "#/definitions/models.Subscription" + "allOf": [ + { + "$ref": "#/definitions/models.Subscription" + } + ] }, "title": { "description": "The title of the project. You'll see this in the overview.", @@ -7734,9 +7719,7 @@ "updated": { "description": "A timestamp when this project was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.ListDuplicate": { @@ -7744,14 +7727,16 @@ "properties": { "list": { "description": "The copied list", - "$ref": "#/definitions/models.List" + "allOf": [ + { + "$ref": "#/definitions/models.List" + } + ] }, "namespace_id": { "description": "The target namespace ID", "type": "integer" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.ListUser": { @@ -7767,9 +7752,13 @@ }, "right": { "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", "default": 0, - "maximum": 2 + "maximum": 2, + "allOf": [ + { + "$ref": "#/definitions/models.Right" + } + ] }, "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", @@ -7778,9 +7767,7 @@ "user_id": { "description": "The username.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.Message": { @@ -7818,11 +7805,19 @@ }, "owner": { "description": "The user who owns this namespace", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "subscription": { "description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.", - "$ref": "#/definitions/models.Subscription" + "allOf": [ + { + "$ref": "#/definitions/models.Subscription" + } + ] }, "title": { "description": "The name of this namespace.", @@ -7833,9 +7828,7 @@ "updated": { "description": "A timestamp when this namespace was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.ProjectUser": { @@ -7851,9 +7844,13 @@ }, "right": { "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", "default": 0, - "maximum": 2 + "maximum": 2, + "allOf": [ + { + "$ref": "#/definitions/models.Right" + } + ] }, "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", @@ -7862,9 +7859,7 @@ "user_id": { "description": "The username.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.NamespaceWithLists": { @@ -7899,11 +7894,19 @@ }, "owner": { "description": "The user who owns this namespace", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "subscription": { "description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.", - "$ref": "#/definitions/models.Subscription" + "allOf": [ + { + "$ref": "#/definitions/models.Subscription" + } + ] }, "title": { "description": "The name of this namespace.", @@ -7914,9 +7917,7 @@ "updated": { "description": "A timestamp when this namespace was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.RelatedTaskMap": { @@ -7928,6 +7929,50 @@ } } }, + "models.RelationKind": { + "type": "string", + "enum": [ + "unknown", + "subtask", + "parenttask", + "related", + "duplicateof", + "duplicates", + "blocking", + "blocked", + "precedes", + "follows", + "copiedfrom", + "copiedto" + ], + "x-enum-varnames": [ + "RelationKindUnknown", + "RelationKindSubtask", + "RelationKindParenttask", + "RelationKindRelated", + "RelationKindDuplicateOf", + "RelationKindDuplicates", + "RelationKindBlocking", + "RelationKindBlocked", + "RelationKindPreceeds", + "RelationKindFollows", + "RelationKindCopiedFrom", + "RelationKindCopiedTo" + ] + }, + "models.Right": { + "type": "integer", + "enum": [ + 0, + 1, + 2 + ], + "x-enum-varnames": [ + "RightRead", + "RightWrite", + "RightAdmin" + ] + }, "models.SavedFilter": { "type": "object", "properties": { @@ -7941,7 +7986,11 @@ }, "filters": { "description": "The actual filters this filter contains", - "$ref": "#/definitions/models.TaskCollection" + "allOf": [ + { + "$ref": "#/definitions/models.TaskCollection" + } + ] }, "id": { "description": "The unique numeric id of this saved filter", @@ -7953,7 +8002,11 @@ }, "owner": { "description": "The user who owns this filter", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "title": { "description": "The title of the filter.", @@ -7964,11 +8017,22 @@ "updated": { "description": "A timestamp when this filter was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, + "models.SharingType": { + "type": "integer", + "enum": [ + 0, + 1, + 2 + ], + "x-enum-varnames": [ + "SharingTypeUnknown", + "SharingTypeWithoutPassword", + "SharingTypeWithPassword" + ] + }, "models.Subscription": { "type": "object", "properties": { @@ -7989,10 +8053,12 @@ }, "user": { "description": "The user who made this subscription", - "$ref": "#/definitions/user.User" - }, - "web.CRUDable": {}, - "web.Rights": {} + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] + } } }, "models.Task": { @@ -8026,7 +8092,11 @@ }, "created_by": { "description": "The user who initially created the task.", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "description": { "description": "The task description.", @@ -8098,7 +8168,11 @@ }, "related_tasks": { "description": "All related tasks, grouped by their relation kind", - "$ref": "#/definitions/models.RelatedTaskMap" + "allOf": [ + { + "$ref": "#/definitions/models.RelatedTaskMap" + } + ] }, "reminders": { "description": "An array of reminders that are associated with this task.", @@ -8113,7 +8187,11 @@ }, "repeat_mode": { "description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.", - "type": "integer" + "allOf": [ + { + "$ref": "#/definitions/models.TaskRepeatMode" + } + ] }, "start_date": { "description": "When this task starts.", @@ -8121,7 +8199,11 @@ }, "subscription": { "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.", - "$ref": "#/definitions/models.Subscription" + "allOf": [ + { + "$ref": "#/definitions/models.Subscription" + } + ] }, "title": { "description": "The task text. This is what you'll see in the project.", @@ -8131,9 +8213,7 @@ "updated": { "description": "A timestamp when this task was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TaskAssginee": { @@ -8144,9 +8224,7 @@ }, "user_id": { "type": "integer" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TaskAttachment": { @@ -8166,9 +8244,7 @@ }, "task_id": { "type": "integer" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TaskCollection": { @@ -8216,9 +8292,7 @@ "items": { "type": "string" } - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TaskComment": { @@ -8238,9 +8312,7 @@ }, "updated": { "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TaskRelation": { @@ -8252,7 +8324,11 @@ }, "created_by": { "description": "The user who created this relation", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "other_task_id": { "description": "The ID of the other task, the task which is being related.", @@ -8260,16 +8336,31 @@ }, "relation_kind": { "description": "The kind of the relation.", - "type": "string" + "allOf": [ + { + "$ref": "#/definitions/models.RelationKind" + } + ] }, "task_id": { "description": "The ID of the \"base\" task, the task which has a relation to another.", "type": "integer" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, + "models.TaskRepeatMode": { + "type": "integer", + "enum": [ + 0, + 1, + 2 + ], + "x-enum-varnames": [ + "TaskRepeatModeDefault", + "TaskRepeatModeMonth", + "TaskRepeatModeFromCurrentDate" + ] + }, "models.Team": { "type": "object", "properties": { @@ -8279,7 +8370,11 @@ }, "created_by": { "description": "The user who created this team.", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "description": { "description": "The team's description.", @@ -8310,9 +8405,7 @@ "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TeamList": { @@ -8328,9 +8421,13 @@ }, "right": { "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", "default": 0, - "maximum": 2 + "maximum": 2, + "allOf": [ + { + "$ref": "#/definitions/models.Right" + } + ] }, "team_id": { "description": "The team id.", @@ -8339,9 +8436,7 @@ "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TeamMember": { @@ -8362,9 +8457,7 @@ "username": { "description": "The username of the member. We use this to prevent automated user id entering.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TeamProject": { @@ -8380,9 +8473,13 @@ }, "right": { "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", "default": 0, - "maximum": 2 + "maximum": 2, + "allOf": [ + { + "$ref": "#/definitions/models.Right" + } + ] }, "team_id": { "description": "The team id.", @@ -8391,9 +8488,7 @@ "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.TeamUser": { @@ -8429,8 +8524,7 @@ "type": "string", "maxLength": 250, "minLength": 1 - }, - "web.Auth": {} + } } }, "models.TeamWithRight": { @@ -8442,7 +8536,11 @@ }, "created_by": { "description": "The user who created this team.", - "$ref": "#/definitions/user.User" + "allOf": [ + { + "$ref": "#/definitions/user.User" + } + ] }, "description": { "description": "The team's description.", @@ -8471,16 +8569,12 @@ "maxLength": 250 }, "right": { - "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", - "default": 0 + "$ref": "#/definitions/models.Right" }, "updated": { "description": "A timestamp when this relation was last updated. You cannot change this value.", "type": "string" - }, - "web.CRUDable": {}, - "web.Rights": {} + } } }, "models.UserWithRight": { @@ -8504,9 +8598,7 @@ "type": "string" }, "right": { - "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "type": "integer", - "default": 0 + "$ref": "#/definitions/models.Right" }, "updated": { "description": "A timestamp when this task was last updated. You cannot change this value.", @@ -8517,8 +8609,7 @@ "type": "string", "maxLength": 250, "minLength": 1 - }, - "web.Auth": {} + } } }, "models.Webhook": { @@ -8800,8 +8891,7 @@ "type": "string", "maxLength": 250, "minLength": 1 - }, - "web.Auth": {} + } } }, "v1.LinkShareAuth": { diff --git a/pkg/swagger/swagger.yaml b/pkg/swagger/swagger.yaml index 0f7c23ea9..b9116fa08 100644 --- a/pkg/swagger/swagger.yaml +++ b/pkg/swagger/swagger.yaml @@ -109,30 +109,9 @@ definitions: value. type: string created_by: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who initially created the bucket. - filter_by: - description: The field name of the field to filter by - items: - type: string - type: array - filter_comparator: - description: The comparator for field and value - items: - type: string - type: array - filter_concat: - description: The way all filter conditions are concatenated together, can - be either "and" or "or"., - type: string - filter_include_nulls: - description: If set to true, the result will also include null values - type: boolean - filter_value: - description: The value of the field name to filter by - items: - type: string - type: array id: description: The unique, numeric id of this bucket. type: integer @@ -143,22 +122,10 @@ definitions: list_id: description: The list this bucket belongs to. type: integer - order_by: - description: The query parameter to order the items by. This can be either - asc or desc, with asc being the default. - items: - type: string - type: array position: description: The position this bucket has when querying all buckets. See the tasks.position property on how to use this. type: number - sort_by: - description: The query parameter to sort by. This is for ex. done, priority, - etc. - items: - type: string - type: array tasks: description: All tasks which belong to this bucket. items: @@ -172,8 +139,6 @@ definitions: description: A timestamp when this bucket was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object models.BulkAssignees: properties: @@ -182,8 +147,6 @@ definitions: items: $ref: '#/definitions/user.User' type: array - web.CRUDable: {} - web.Rights: {} type: object models.BulkTask: properties: @@ -209,7 +172,8 @@ definitions: value. type: string created_by: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who initially created the task. description: description: The task description. @@ -274,7 +238,8 @@ definitions: description: The project this task belongs to. type: integer related_tasks: - $ref: '#/definitions/models.RelatedTaskMap' + allOf: + - $ref: '#/definitions/models.RelatedTaskMap' description: All related tasks, grouped by their relation kind reminders: description: An array of reminders that are associated with this task. @@ -287,16 +252,18 @@ definitions: increase all remindes and the due date by its amount. type: integer repeat_mode: + allOf: + - $ref: '#/definitions/models.TaskRepeatMode' description: 'Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.' - type: integer start_date: description: When this task starts. type: string subscription: - $ref: '#/definitions/models.Subscription' + allOf: + - $ref: '#/definitions/models.Subscription' description: |- The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it. Will only returned when retrieving one task. @@ -313,8 +280,6 @@ definitions: description: A timestamp when this task was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object models.DatabaseNotifications: properties: @@ -339,8 +304,6 @@ definitions: description: When this notification is marked as read, this will be updated with the current timestamp. type: string - web.CRUDable: {} - web.Rights: {} type: object models.Label: properties: @@ -349,7 +312,8 @@ definitions: value. type: string created_by: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who created this label description: description: The label description. @@ -371,8 +335,6 @@ definitions: description: A timestamp when this label was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object models.LabelTask: properties: @@ -383,8 +345,6 @@ definitions: label_id: description: The label id you want to associate with a task. type: integer - web.CRUDable: {} - web.Rights: {} type: object models.LabelTaskBulk: properties: @@ -393,8 +353,6 @@ definitions: items: $ref: '#/definitions/models.Label' type: array - web.CRUDable: {} - web.Rights: {} type: object models.LinkSharing: properties: @@ -417,26 +375,27 @@ definitions: it after the link share has been created. type: string right: + allOf: + - $ref: '#/definitions/models.Right' default: 0 description: The right this project is shared with. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details. maximum: 2 - type: integer shared_by: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who shared this list sharing_type: + allOf: + - $ref: '#/definitions/models.SharingType' default: 0 description: The kind of this link. 0 = undefined, 1 = without password, 2 = with password. maximum: 2 - type: integer updated: description: A timestamp when this share was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object models.Message: properties: @@ -491,14 +450,16 @@ definitions: to the api. type: boolean owner: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who created this list. position: description: The position this project has when querying all projects. See the tasks.position property on how to use this. type: number subscription: - $ref: '#/definitions/models.Subscription' + allOf: + - $ref: '#/definitions/models.Subscription' description: |- The subscription status for the user reading this project. You can only read this property, use the subscription endpoints to modify it. Will only returned when retreiving one project. @@ -511,19 +472,16 @@ definitions: description: A timestamp when this project was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object models.ListDuplicate: properties: list: - $ref: '#/definitions/models.List' + allOf: + - $ref: '#/definitions/models.List' description: The copied list namespace_id: description: The target namespace ID type: integer - web.CRUDable: {} - web.Rights: {} type: object models.ListUser: properties: @@ -535,11 +493,12 @@ definitions: description: The unique, numeric id of this list <-> user relation. type: integer right: + allOf: + - $ref: '#/definitions/models.Right' default: 0 description: The right this user has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details. maximum: 2 - type: integer updated: description: A timestamp when this relation was last updated. You cannot change this value. @@ -547,8 +506,6 @@ definitions: user_id: description: The username. type: string - web.CRUDable: {} - web.Rights: {} type: object models.Message: properties: @@ -576,10 +533,12 @@ definitions: description: Whether or not a namespace is archived. type: boolean owner: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who owns this namespace subscription: - $ref: '#/definitions/models.Subscription' + allOf: + - $ref: '#/definitions/models.Subscription' description: |- The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it. Will only returned when retreiving one namespace. @@ -592,8 +551,6 @@ definitions: description: A timestamp when this namespace was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object models.ProjectUser: properties: @@ -605,11 +562,12 @@ definitions: description: The unique, numeric id of this project <-> user relation. type: integer right: + allOf: + - $ref: '#/definitions/models.Right' default: 0 description: The right this user has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details. maximum: 2 - type: integer updated: description: A timestamp when this relation was last updated. You cannot change this value. @@ -617,8 +575,6 @@ definitions: user_id: description: The username. type: string - web.CRUDable: {} - web.Rights: {} type: object models.NamespaceWithLists: properties: @@ -644,10 +600,12 @@ definitions: $ref: '#/definitions/models.List' type: array owner: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who owns this namespace subscription: - $ref: '#/definitions/models.Subscription' + allOf: + - $ref: '#/definitions/models.Subscription' description: |- The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it. Will only returned when retreiving one namespace. @@ -660,8 +618,6 @@ definitions: description: A timestamp when this namespace was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object models.RelatedTaskMap: additionalProperties: @@ -669,6 +625,44 @@ definitions: $ref: '#/definitions/models.Task' type: array type: object + models.RelationKind: + enum: + - unknown + - subtask + - parenttask + - related + - duplicateof + - duplicates + - blocking + - blocked + - precedes + - follows + - copiedfrom + - copiedto + type: string + x-enum-varnames: + - RelationKindUnknown + - RelationKindSubtask + - RelationKindParenttask + - RelationKindRelated + - RelationKindDuplicateOf + - RelationKindDuplicates + - RelationKindBlocking + - RelationKindBlocked + - RelationKindPreceeds + - RelationKindFollows + - RelationKindCopiedFrom + - RelationKindCopiedTo + models.Right: + enum: + - 0 + - 1 + - 2 + type: integer + x-enum-varnames: + - RightRead + - RightWrite + - RightAdmin models.SavedFilter: properties: created: @@ -679,7 +673,8 @@ definitions: description: The description of the filter type: string filters: - $ref: '#/definitions/models.TaskCollection' + allOf: + - $ref: '#/definitions/models.TaskCollection' description: The actual filters this filter contains id: description: The unique numeric id of this saved filter @@ -689,7 +684,8 @@ definitions: a separate parent project together with favorite projects. type: boolean owner: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who owns this filter title: description: The title of the filter. @@ -700,9 +696,17 @@ definitions: description: A timestamp when this filter was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object + models.SharingType: + enum: + - 0 + - 1 + - 2 + type: integer + x-enum-varnames: + - SharingTypeUnknown + - SharingTypeWithoutPassword + - SharingTypeWithPassword models.Subscription: properties: created: @@ -718,10 +722,9 @@ definitions: description: The numeric ID of the subscription type: integer user: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who made this subscription - web.CRUDable: {} - web.Rights: {} type: object models.Task: properties: @@ -747,7 +750,8 @@ definitions: value. type: string created_by: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who initially created the task. description: description: The task description. @@ -812,7 +816,8 @@ definitions: description: The project this task belongs to. type: integer related_tasks: - $ref: '#/definitions/models.RelatedTaskMap' + allOf: + - $ref: '#/definitions/models.RelatedTaskMap' description: All related tasks, grouped by their relation kind reminders: description: An array of reminders that are associated with this task. @@ -825,16 +830,18 @@ definitions: increase all remindes and the due date by its amount. type: integer repeat_mode: + allOf: + - $ref: '#/definitions/models.TaskRepeatMode' description: 'Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.' - type: integer start_date: description: When this task starts. type: string subscription: - $ref: '#/definitions/models.Subscription' + allOf: + - $ref: '#/definitions/models.Subscription' description: |- The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it. Will only returned when retrieving one task. @@ -846,8 +853,6 @@ definitions: description: A timestamp when this task was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object models.TaskAssginee: properties: @@ -855,8 +860,6 @@ definitions: type: string user_id: type: integer - web.CRUDable: {} - web.Rights: {} type: object models.TaskAttachment: properties: @@ -870,8 +873,6 @@ definitions: type: integer task_id: type: integer - web.CRUDable: {} - web.Rights: {} type: object models.TaskCollection: properties: @@ -909,8 +910,6 @@ definitions: items: type: string type: array - web.CRUDable: {} - web.Rights: {} type: object models.TaskComment: properties: @@ -924,8 +923,6 @@ definitions: type: integer updated: type: string - web.CRUDable: {} - web.Rights: {} type: object models.TaskRelation: properties: @@ -934,20 +931,30 @@ definitions: value. type: string created_by: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who created this relation other_task_id: description: The ID of the other task, the task which is being related. type: integer relation_kind: + allOf: + - $ref: '#/definitions/models.RelationKind' description: The kind of the relation. - type: string task_id: description: The ID of the "base" task, the task which has a relation to another. type: integer - web.CRUDable: {} - web.Rights: {} type: object + models.TaskRepeatMode: + enum: + - 0 + - 1 + - 2 + type: integer + x-enum-varnames: + - TaskRepeatModeDefault + - TaskRepeatModeMonth + - TaskRepeatModeFromCurrentDate models.Team: properties: created: @@ -955,7 +962,8 @@ definitions: this value. type: string created_by: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who created this team. description: description: The team's description. @@ -981,8 +989,6 @@ definitions: description: A timestamp when this relation was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object models.TeamList: properties: @@ -994,11 +1000,12 @@ definitions: description: The unique, numeric id of this list <-> team relation. type: integer right: + allOf: + - $ref: '#/definitions/models.Right' default: 0 description: The right this team has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details. maximum: 2 - type: integer team_id: description: The team id. type: integer @@ -1006,8 +1013,6 @@ definitions: description: A timestamp when this relation was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object models.TeamMember: properties: @@ -1026,8 +1031,6 @@ definitions: description: The username of the member. We use this to prevent automated user id entering. type: string - web.CRUDable: {} - web.Rights: {} type: object models.TeamProject: properties: @@ -1039,11 +1042,12 @@ definitions: description: The unique, numeric id of this project <-> team relation. type: integer right: + allOf: + - $ref: '#/definitions/models.Right' default: 0 description: The right this team has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details. maximum: 2 - type: integer team_id: description: The team id. type: integer @@ -1051,8 +1055,6 @@ definitions: description: A timestamp when this relation was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object models.TeamUser: properties: @@ -1083,7 +1085,6 @@ definitions: maxLength: 250 minLength: 1 type: string - web.Auth: {} type: object models.TeamWithRight: properties: @@ -1092,7 +1093,8 @@ definitions: this value. type: string created_by: - $ref: '#/definitions/user.User' + allOf: + - $ref: '#/definitions/user.User' description: The user who created this team. description: description: The team's description. @@ -1115,16 +1117,11 @@ definitions: maxLength: 250 type: string right: - default: 0 - description: The right this team has. 0 = Read only, 1 = Read & Write, 2 = - Admin. See the docs for more details. - type: integer + $ref: '#/definitions/models.Right' updated: description: A timestamp when this relation was last updated. You cannot change this value. type: string - web.CRUDable: {} - web.Rights: {} type: object models.UserWithRight: properties: @@ -1143,10 +1140,7 @@ definitions: description: The full name of the user. type: string right: - default: 0 - description: The right this user has. 0 = Read only, 1 = Read & Write, 2 = - Admin. See the docs for more details. - type: integer + $ref: '#/definitions/models.Right' updated: description: A timestamp when this task was last updated. You cannot change this value. @@ -1156,7 +1150,6 @@ definitions: maxLength: 250 minLength: 1 type: string - web.Auth: {} type: object models.Webhook: properties: @@ -1364,7 +1357,6 @@ definitions: maxLength: 250 minLength: 1 type: string - web.Auth: {} type: object v1.LinkShareAuth: properties: -- 2.45.1 From 2af1679dafeca17793df2c7fa62d70eed2df4f6c Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 30 Mar 2023 17:15:24 +0200 Subject: [PATCH 61/93] return single team for GetTeamByOidcIDAndName --- pkg/models/teams.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 9223c6d53..964320bc4 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -20,7 +20,6 @@ import ( "time" "code.vikunja.io/api/pkg/db" - "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/events" "code.vikunja.io/api/pkg/user" @@ -151,15 +150,16 @@ func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { // GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters // For oidc team creation oidcID and Name need to be set func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (team Team, err error) { - exists, err := s. + err = s. Table("teams"). Where("oidc_id = ? AND name = ?", oidcID, teamName). - Get(&team) - log.Debugf("GetTeamByOidcIDAndName: %v, exists: %v", team.Name, exists) - if exists && err == nil { - return team, nil + OrderBy("name ASC"). + Limit(1). + Find(&team) + if err != nil { + return team, ErrOIDCTeamDoesNotExist{teamName, oidcID} } - return team, ErrOIDCTeamDoesNotExist{teamName, oidcID} + return team, err } func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err error) { -- 2.45.1 From 3f4b3853a3a50aeb46159df4c6da5d7a5ec30518 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 8 May 2023 15:41:24 +0200 Subject: [PATCH 62/93] fix limit GetTeamByOidcIDAndName to get a single team --- pkg/models/teams.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 964320bc4..c46c86b39 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -150,13 +150,13 @@ func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { // GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters // For oidc team creation oidcID and Name need to be set func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (team Team, err error) { - err = s. + has, err := s. Table("teams"). Where("oidc_id = ? AND name = ?", oidcID, teamName). - OrderBy("name ASC"). + Asc("id"). Limit(1). - Find(&team) - if err != nil { + Get(&team) + if !has || err != nil { return team, ErrOIDCTeamDoesNotExist{teamName, oidcID} } return team, err -- 2.45.1 From 73085963706acd47336b1927cb36fd4117631b11 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 8 May 2023 15:42:02 +0200 Subject: [PATCH 63/93] work on instructions for openid.md --- pkg/modules/auth/openid/openid.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/modules/auth/openid/openid.md b/pkg/modules/auth/openid/openid.md index 864b66614..98be2211a 100644 --- a/pkg/modules/auth/openid/openid.md +++ b/pkg/modules/auth/openid/openid.md @@ -1,8 +1,10 @@ # Assign teams via oidc -This PR adds the functionality to assign users to teams via oidc. +Adds the functionality to assign users to teams via oidc. Read carefully and brief your administrators to use this feature. +You need to configure your oidc provider as explained in the documentation below to make this feature work. Tested with oidc provider authentik. -To distinguish between teams created in vikunja and teams generated via oidc, an attribute for vikunja teams is introduced, which is called: *oidcID* +To distinguish between teams created in vikunja and teams generated via oidc, a string attribute for vikunja teams is introduced, which is called: *oidcID* +You should conigure your provider to send an oidcID to vikunja. ## Setup -- 2.45.1 From 46a6456bae2357b75235ad0138c42ef241daade3 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 8 May 2023 15:51:58 +0200 Subject: [PATCH 64/93] work on openid to just start group workflow when teamData is available --- pkg/modules/auth/openid/openid.go | 39 ++++++++++++++++++------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index adbdaaa8b..444c84974 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -203,23 +203,24 @@ func HandleCallback(c echo.Context) error { // does the oidc token contain well formed "vikunja_groups" through vikunja_scope teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, provider) - for _, err := range errs { - log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) - } + if teamData != nil { + for _, err := range errs { + log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) + } - //find old teams for user through oidc - oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) - if err != nil { - log.Errorf("No Oidc Teams found for user %v", err) - } - oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) - if err != nil { - log.Errorf("Could not proceed with group routine %v", err) - } - errs = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) - log.Errorf("%v", errs) - for _, err := range errs { - log.Errorf("Found Error while signing out from teams %v", err) + //find old teams for user through oidc + oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) + if err != nil { + log.Errorf("No Oidc Teams found for user %v", err) + } + oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) + if err != nil { + log.Errorf("Could not proceed with group routine %v", err) + } + errs = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + for _, err := range errs { + log.Errorf("Found Error while signing out from teams %v", err) + } } err = s.Commit() if err != nil { @@ -254,8 +255,10 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models. for _, err := range errs { log.Errorf("Found Error while signing out from teams %v", err) } + oidcTeams = append(oidcTeams, team.ID) } return oidcTeams, err +<<<<<<< HEAD func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.OIDCTeamData) (oidcTeams []int64, err error) { if len(teamData) == 0 { @@ -285,6 +288,10 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models. ======= >>>>>>> 169b668c... remove left over function GetMemberCount, rename function SignOut to RemoveFrom +======= +} + +>>>>>>> 3fdbd53b... work on openid to just start group workflow when teamData is available func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (errs []error) { errs = []error{} for _, teamID := range teamIDs { -- 2.45.1 From da12af713583a09c6b4e92247c93a35c74c1eda8 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 8 May 2023 16:04:49 +0200 Subject: [PATCH 65/93] refactor unused function GetTeamsByName --- pkg/models/error.go | 27 ++------------------------- pkg/models/teams.go | 18 ------------------ 2 files changed, 2 insertions(+), 43 deletions(-) diff --git a/pkg/models/error.go b/pkg/models/error.go index eda0c56cd..d3fb90d14 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1225,29 +1225,6 @@ func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Teams with property oidcId could be found for User."} } -// ErrTeamsDoNotExist represents an error where Teams searched via non-unique name do not exist. -type ErrTeamsDoNotExist struct { - Name string -} - -// IsErrTeamsDoNotExist checks if an error is ErrTeamsDoNotExist. -func IsErrTeamsDoNotExist(err error) bool { - _, ok := err.(ErrTeamsDoNotExist) - return ok -} - -func (err ErrTeamsDoNotExist) Error() string { - return fmt.Sprintf("No teams with that name exist [Team Name: %v]", err.Name) -} - -// ErrCodeTeamsDoesNotExist holds the unique world-error code of this error -const ErrCodeTeamsDoNotExist = 6008 - -// HTTPError holds the http error description -func (err ErrTeamsDoNotExist) HTTPError() web.HTTPError { - return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No teams with that name exist"} -} - // ErrOIDCTeamDoesNotExist represents an error where a team with specified name and specified oidcId property does not exist type ErrOIDCTeamDoesNotExist struct { OidcID string @@ -1266,7 +1243,7 @@ func (err ErrOIDCTeamDoesNotExist) Error() string { } // ErrCodeTeamDoesNotExist holds the unique world-error code of this error -const ErrCodeOIDCTeamDoesNotExist = 6009 +const ErrCodeOIDCTeamDoesNotExist = 6008 // HTTPError holds the http error description func (err ErrOIDCTeamDoesNotExist) HTTPError() web.HTTPError { @@ -1289,7 +1266,7 @@ func (err ErrOIDCTeamsDoNotExistForUser) Error() string { } // ErrCodeTeamDoesNotExist holds the unique world-error code of this error -const ErrCodeOIDCTeamsDoNotExistForUser = 6010 +const ErrCodeOIDCTeamsDoNotExistForUser = 6009 // HTTPError holds the http error description func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError { diff --git a/pkg/models/teams.go b/pkg/models/teams.go index c46c86b39..2628944a0 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -129,24 +129,6 @@ func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) { return } -// GetTeamByName gets teams by name -func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) { - if name == "" { - return teams, ErrTeamsDoNotExist{name} - } - - var ts []*Team - - err = s. - Where("name = ?", name). - Find(&ts) - if err != nil || len(ts) == 0 { - return ts, ErrTeamsDoNotExist{name} - } - teams = ts - return teams, err -} - // GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters // For oidc team creation oidcID and Name need to be set func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (team Team, err error) { -- 2.45.1 From 583fe9a655f9cd92e4279539236ece2421bc9ce4 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 8 May 2023 16:54:00 +0200 Subject: [PATCH 66/93] fix rebase error --- pkg/models/error.go | 48 --------------------------------------------- 1 file changed, 48 deletions(-) diff --git a/pkg/models/error.go b/pkg/models/error.go index d3fb90d14..51f30ceab 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1225,54 +1225,6 @@ func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Teams with property oidcId could be found for User."} } -// ErrOIDCTeamDoesNotExist represents an error where a team with specified name and specified oidcId property does not exist -type ErrOIDCTeamDoesNotExist struct { - OidcID string - Name string -} - -// IsErrOIDCTeamDoesNotExist checks if an error is ErrOIDCTeamDoesNotExist. -func IsErrOIDCTeamDoesNotExist(err error) bool { - _, ok := err.(ErrOIDCTeamDoesNotExist) - return ok -} - -// ErrTeamDoesNotExist represents an error where a team does not exist -func (err ErrOIDCTeamDoesNotExist) Error() string { - return fmt.Sprintf("No Team with that name and valid property oidcId could be found [Team Name: %v] [OidcId : %v] ", err.Name, err.OidcID) -} - -// ErrCodeTeamDoesNotExist holds the unique world-error code of this error -const ErrCodeOIDCTeamDoesNotExist = 6008 - -// HTTPError holds the http error description -func (err ErrOIDCTeamDoesNotExist) HTTPError() web.HTTPError { - return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Team with that name and valid property oidcId could be found."} -} - -// ErrOIDCTeamsDoNotExistForUser represents an error where an oidcTeam does not exist for the user -type ErrOIDCTeamsDoNotExistForUser struct { - UserID int64 -} - -// IsErrOIDCTeamsDoNotExistForUser checks if an error is ErrOIDCTeamsDoNotExistForUser. -func IsErrOIDCTeamsDoNotExistForUser(err error) bool { - _, ok := err.(ErrOIDCTeamsDoNotExistForUser) - return ok -} - -func (err ErrOIDCTeamsDoNotExistForUser) Error() string { - return fmt.Sprintf("No Teams with property oidcId could be found for User [User ID: %d]", err.UserID) -} - -// ErrCodeTeamDoesNotExist holds the unique world-error code of this error -const ErrCodeOIDCTeamsDoNotExistForUser = 6009 - -// HTTPError holds the http error description -func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError { - return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Teams with property oidcId could be found for User."} -} - // ==================== // User <-> Project errors // ==================== -- 2.45.1 From 7019a7206578d26160fa1239520c80dc7d55086f Mon Sep 17 00:00:00 2001 From: viehlieb Date: Tue, 9 May 2023 13:34:23 +0200 Subject: [PATCH 67/93] add to error.md change error msg --- docs/content/doc/usage/errors.md | 1 + pkg/models/error.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/content/doc/usage/errors.md b/docs/content/doc/usage/errors.md index 85bc5722e..4c257a966 100644 --- a/docs/content/doc/usage/errors.md +++ b/docs/content/doc/usage/errors.md @@ -44,6 +44,7 @@ This document describes the different errors Vikunja can return. | 1020 | 412 | This user account is disabled. | | 1021 | 412 | This account is managed by a third-party authentication provider. | | 1021 | 412 | The username must not contain spaces. | +| 1022 | 412 | The custom scope set by the OIDC provider is malformed. Please make sure the openid provider sets the data correctly for your scope. Check especially to have set an oidcID. | ## Validation diff --git a/pkg/models/error.go b/pkg/models/error.go index 51f30ceab..40a7b1c02 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1191,7 +1191,7 @@ func IsErrOIDCTeamDoesNotExist(err error) bool { // ErrTeamDoesNotExist represents an error where a team does not exist func (err ErrOIDCTeamDoesNotExist) Error() string { - return fmt.Sprintf("No Team with that name and valid property oidcId could be found [Team Name: %v] [OidcId : %v] ", err.Name, err.OidcID) + return fmt.Sprintf("No Team with that name and valid oidcId could be found. [Team Name: %v] [OidcId : %v] ", err.Name, err.OidcID) } // ErrCodeTeamDoesNotExist holds the unique world-error code of this error @@ -1199,7 +1199,7 @@ const ErrCodeOIDCTeamDoesNotExist = 6008 // HTTPError holds the http error description func (err ErrOIDCTeamDoesNotExist) HTTPError() web.HTTPError { - return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Team with that name and valid property oidcId could be found."} + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Team with that name and valid oidcId could be found."} } // ErrOIDCTeamsDoNotExistForUser represents an error where an oidcTeam does not exist for the user -- 2.45.1 From 6d33a513be8ce00f385a9d86a9603183438e9325 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Tue, 9 May 2023 13:34:44 +0200 Subject: [PATCH 68/93] return pointer to team --- pkg/models/teams.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 2628944a0..1f355a9c0 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -131,17 +131,18 @@ func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) { // GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters // For oidc team creation oidcID and Name need to be set -func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (team Team, err error) { +func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (*Team, error) { + team := &Team{} has, err := s. Table("teams"). Where("oidc_id = ? AND name = ?", oidcID, teamName). Asc("id"). Limit(1). - Get(&team) + Get(team) if !has || err != nil { - return team, ErrOIDCTeamDoesNotExist{teamName, oidcID} + return nil, ErrOIDCTeamDoesNotExist{teamName, oidcID} } - return team, err + return team, nil } func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err error) { -- 2.45.1 From c398436ad7dd2b55b32eb7312fced84f6b737ac0 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Tue, 9 May 2023 13:36:23 +0200 Subject: [PATCH 69/93] change error note and append team pointer in GetOrCreateTeamsByOIDCAndNames --- pkg/modules/auth/openid/openid.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 444c84974..d989e66a3 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -277,7 +277,7 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models. if !exists { err = tm.Create(s, u) if err != nil { - log.Errorf("Could not assign %v to %v. %v", u.Username, team.Name, err) + log.Errorf("Could not assign user %s to team %s: %v", u.Username, team.Name, err) } } oidcTeams = append(oidcTeams, team.ID) @@ -374,7 +374,7 @@ func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.OIDCTeamD te = append(te, newTeam) } else { log.Debugf("Team with oidc_id %v and name %v already exists.", team.OidcID, team.Name) - te = append(te, &team) + te = append(te, team) } } return te, err -- 2.45.1 From 901166851243738755ee1e73719ff247a7241fc5 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 15 May 2023 14:15:06 +0200 Subject: [PATCH 70/93] change openid.md directory, modify openid.md --- .../content/doc/setup}/openid.md | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) rename {pkg/modules/auth/openid => docs/content/doc/setup}/openid.md (51%) diff --git a/pkg/modules/auth/openid/openid.md b/docs/content/doc/setup/openid.md similarity index 51% rename from pkg/modules/auth/openid/openid.md rename to docs/content/doc/setup/openid.md index 98be2211a..fd6487ebd 100644 --- a/pkg/modules/auth/openid/openid.md +++ b/docs/content/doc/setup/openid.md @@ -1,23 +1,20 @@ # Assign teams via oidc -Adds the functionality to assign users to teams via oidc. -Read carefully and brief your administrators to use this feature. -You need to configure your oidc provider as explained in the documentation below to make this feature work. -Tested with oidc provider authentik. -To distinguish between teams created in vikunja and teams generated via oidc, a string attribute for vikunja teams is introduced, which is called: *oidcID* -You should conigure your provider to send an oidcID to vikunja. +Vikunja is capable of automatically adding users to a team based on a group defined in the oidc provider. If used, Vikunja will sync teams, automatically create new ones and make sure the members are part of the configured teams. Teams which only exist because they are generated from oidc attributes are not configurable in Vikunja. -## Setup +See below for setup instructions. -Edit [config.yml](https://kolaente.dev/vikunja/api/src/branch/main/config.yml.sample) to include scope: openid profile email vikunja_scope +To distinguish between teams created in Vikunja and teams generated automatically via oidc, generated teams have an `oidcID` assigned internally. -For authentik to use group assignment feature: -- go to: .../if/admin/#/core/property-mappings +## Setup for atuhentik -- create a new mapping called "vikunja_scope" +To configure automatic team management through authentik, we assume you have already set up Authentik as an oidc provider for authentication with Vikunja. -There is a field to enter python expressions that will be delivered with the oidc token. +To use Authentik's group assignment feature, follow these steps: -- write a small script, for adding group information to vikunja_scope. +1. Edit [config.yml](https://kolaente.dev/vikunja/api/src/branch/main/config.yml.sample) to include scope: `openid profile email vikunja_scope` +2. Open `/if/admin/#/core/property-mappings` +3. Create a new mapping called `vikunja_scope`. There is a field to enter python expressions that will be delivered with the oidc token. +4. Write a small script like this to add group information to `vikunja_scope`: ```python @@ -25,8 +22,9 @@ groupsDict = {"vikunja_groups": []} for group in request.user.ak_groups.all(): groupsDict["vikunja_groups"].append({"name": group.name, "oidcID": group.num_pk}) return groupsDict +``` -""" +``` output example: { "vikunja_groups": [ @@ -40,21 +38,27 @@ output example: } ] } -""" ``` +Now when you log into Vikunja via oidc there will be a list of scopes you are claiming from your oidc provider. +You should see the description you entered in the oidc provider's admin area. -Now when you log in via oidc there will be a list of scopes you are claiming from your oidc provider. -You should see "the description you entered in the oidc provider's admin area" +Log in and go to teams. +You should see "(sso: XXXXX)" written next to each team you were asigned through oidc. -- Log in and go to teams. -- You will see "(sso: XXXXX)" written next to each team you were asigned through oidc. +## IMPORTANT NOTES: +* **SSO/OIDC teams cannot be edited.** + +* **It is required to deliver the key "vikunja_groups" via your custom_scope since this is the key vikunja is looking for to start the procedure.** + +* **Additionally, make sure to deliver an "oidcID" and a "name" attribute in the oidc token.** -____________________________________________________________________________ + +--- ## BEHAVIOR -*(.. examples for "team1" ..)* +*All examples assume one team called "team 1"* 1. *Token delivers team.name +team.oidcId and Vikunja team does not exist:* \ New team will be created called "team 1" with attribute oidcId: "33929" -- 2.45.1 From af2460c1f98ad4e09433b6c5334eee0209372a0a Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 27 Oct 2023 16:30:20 +0200 Subject: [PATCH 71/93] fixsomerebase errs --- pkg/models/teams.go | 29 ------------------------- pkg/modules/auth/openid/openid.go | 35 ------------------------------- 2 files changed, 64 deletions(-) diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 1f355a9c0..7ccbe560a 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -159,35 +159,6 @@ func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err e return ts, nil } -// GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters -// For oidc team creation oidcID and Name need to be set -func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (team Team, err error) { - has, err := s. - Table("teams"). - Where("oidc_id = ? AND name = ?", oidcID, teamName). - Asc("id"). - Limit(1). - Get(&team) - if !has || err != nil { - return team, ErrOIDCTeamDoesNotExist{teamName, oidcID} - } - return team, err -} - -func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err error) { - err = s. - Table("team_members"). - Where("user_id = ? ", userID). - Join("RIGHT", "teams", "teams.id = team_members.team_id"). - Where("teams.oidc_id != ? AND teams.oidc_id IS NOT NULL", ""). - Cols("teams.id"). - Find(&ts) - if ts == nil || err != nil { - return ts, ErrOIDCTeamsDoNotExistForUser{userID} - } - return ts, nil -} - func addMoreInfoToTeams(s *xorm.Session, teams []*Team) (err error) { if len(teams) == 0 { diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index d989e66a3..948d92d22 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -232,34 +232,6 @@ func HandleCallback(c echo.Context) error { return auth.NewUserAuthTokenResponse(u, c, false) } -func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.OIDCTeamData) (oidcTeams []int64, err error) { - if len(teamData) > 0 { - // check if we have seen these teams before. - // find or create Teams and assign user as teammember. - teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u) - if err != nil { - log.Errorf("Error verifying team for %v, got %v. Error: %v", u.Name, teams, err) - return nil, err - } - - //find old teams for user through oidc - oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) - if err != nil { - log.Errorf("No Oidc Teams found for user %v", err) - } - oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) - if err != nil { - log.Errorf("Could not proceed with group routine %v", err) - } - errs = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) - for _, err := range errs { - log.Errorf("Found Error while signing out from teams %v", err) - } - oidcTeams = append(oidcTeams, team.ID) - } - return oidcTeams, err -<<<<<<< HEAD - func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.OIDCTeamData) (oidcTeams []int64, err error) { if len(teamData) == 0 { return @@ -284,14 +256,7 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models. } return oidcTeams, err } -<<<<<<< HEAD -======= ->>>>>>> 169b668c... remove left over function GetMemberCount, rename function SignOut to RemoveFrom -======= -} - ->>>>>>> 3fdbd53b... work on openid to just start group workflow when teamData is available func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (errs []error) { errs = []error{} for _, teamID := range teamIDs { -- 2.45.1 From 9b4be16d501ad03665082ff5ada3462f0d8aa47c Mon Sep 17 00:00:00 2001 From: viehlieb Date: Tue, 7 Nov 2023 15:21:41 +0100 Subject: [PATCH 72/93] do-the swag --- pkg/swagger/docs.go | 323 +-------------------------------------- pkg/swagger/swagger.json | 258 ++++++++----------------------- pkg/swagger/swagger.yaml | 193 ++++++----------------- 3 files changed, 108 insertions(+), 666 deletions(-) diff --git a/pkg/swagger/docs.go b/pkg/swagger/docs.go index 64a6ee8e2..59123e5d4 100644 --- a/pkg/swagger/docs.go +++ b/pkg/swagger/docs.go @@ -7287,43 +7287,14 @@ const docTemplate = `{ "type": "integer", "minimum": 0 }, -<<<<<<< HEAD -======= - "list_id": { - "description": "The list this bucket belongs to.", - "type": "integer" - }, -<<<<<<< HEAD - "order_by": { - "description": "The query parameter to order the items by. This can be either asc or desc, with asc being the default.", - "type": "array", - "items": { - "type": "string" - } - }, ->>>>>>> 4567a680... do the swag -======= ->>>>>>> 85307ce6... add swagger files "position": { "description": "The position this bucket has when querying all buckets. See the tasks.position property on how to use this.", "type": "number" }, -<<<<<<< HEAD -<<<<<<< HEAD "project_id": { "description": "The project this bucket belongs to.", "type": "integer" -======= - "sort_by": { - "description": "The query parameter to sort by. This is for ex. done, priority, etc.", - "type": "array", - "items": { - "type": "string" - } ->>>>>>> 4567a680... do the swag }, -======= ->>>>>>> 85307ce6... add swagger files "tasks": { "description": "All tasks which belong to this bucket.", "type": "array", @@ -7491,25 +7462,12 @@ const docTemplate = `{ "type": "string" }, "subscription": { -<<<<<<< HEAD "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retrieving one task.", "allOf": [ { "$ref": "#/definitions/models.Subscription" } ] -======= - "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.", -<<<<<<< HEAD - "$ref": "#/definitions/models.Subscription" ->>>>>>> 4567a680... do the swag -======= - "allOf": [ - { - "$ref": "#/definitions/models.Subscription" - } - ] ->>>>>>> 85307ce6... add swagger files }, "task_ids": { "description": "A project of task ids to update", @@ -7646,15 +7604,7 @@ const docTemplate = `{ "type": "string" }, "right": { -<<<<<<< HEAD "description": "The right this project is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", -======= - "description": "The right this list is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", -<<<<<<< HEAD - "type": "integer", ->>>>>>> 4567a680... do the swag -======= ->>>>>>> 85307ce6... add swagger files "default": 0, "maximum": 2, "allOf": [ @@ -7664,25 +7614,12 @@ const docTemplate = `{ ] }, "shared_by": { -<<<<<<< HEAD "description": "The user who shared this project", "allOf": [ { "$ref": "#/definitions/user.User" } ] -======= - "description": "The user who shared this list", -<<<<<<< HEAD - "$ref": "#/definitions/user.User" ->>>>>>> 4567a680... do the swag -======= - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] ->>>>>>> 85307ce6... add swagger files }, "sharing_type": { "description": "The kind of this link. 0 = undefined, 1 = without password, 2 = with password.", @@ -7759,53 +7696,27 @@ const docTemplate = `{ "type": "boolean" }, "owner": { -<<<<<<< HEAD "description": "The user who created this project.", "allOf": [ { "$ref": "#/definitions/user.User" } ] -======= - "description": "The user who created this list.", -<<<<<<< HEAD - "$ref": "#/definitions/user.User" ->>>>>>> 4567a680... do the swag }, "parent_project_id": { "type": "integer" -======= - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] ->>>>>>> 85307ce6... add swagger files }, "position": { "description": "The position this project has when querying all projects. See the tasks.position property on how to use this.", "type": "number" }, "subscription": { -<<<<<<< HEAD "description": "The subscription status for the user reading this project. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one project.", "allOf": [ { "$ref": "#/definitions/models.Subscription" } ] -======= - "description": "The subscription status for the user reading this list. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one list.", -<<<<<<< HEAD - "$ref": "#/definitions/models.Subscription" ->>>>>>> 4567a680... do the swag -======= - "allOf": [ - { - "$ref": "#/definitions/models.Subscription" - } - ] ->>>>>>> 85307ce6... add swagger files }, "title": { "description": "The title of the project. You'll see this in the overview.", @@ -7819,7 +7730,6 @@ const docTemplate = `{ } } }, -<<<<<<< HEAD "models.ProjectDuplicate": { "type": "object", "properties": { @@ -7835,121 +7745,6 @@ const docTemplate = `{ "description": "The target parent project", "type": "integer" } -======= - "models.ListDuplicate": { - "type": "object", - "properties": { - "list": { - "description": "The copied list", - "allOf": [ - { - "$ref": "#/definitions/models.List" - } - ] - }, - "namespace_id": { - "description": "The target namespace ID", - "type": "integer" - } - } - }, - "models.ListUser": { - "type": "object", - "properties": { - "created": { - "description": "A timestamp when this relation was created. You cannot change this value.", - "type": "string" - }, - "id": { - "description": "The unique, numeric id of this list \u003c-\u003e user relation.", - "type": "integer" - }, - "right": { - "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "default": 0, - "maximum": 2, - "allOf": [ - { - "$ref": "#/definitions/models.Right" - } - ] - }, - "updated": { - "description": "A timestamp when this relation was last updated. You cannot change this value.", - "type": "string" - }, - "user_id": { - "description": "The username.", - "type": "string" - } - } - }, - "models.Message": { - "type": "object", - "properties": { - "message": { - "description": "A standard message.", - "type": "string" - } - } - }, - "models.Namespace": { - "type": "object", - "properties": { - "created": { - "description": "A timestamp when this namespace was created. You cannot change this value.", - "type": "string" - }, - "description": { - "description": "The description of the namespace", - "type": "string" - }, - "hex_color": { - "description": "The hex color of this namespace", - "type": "string", - "maxLength": 6 - }, - "id": { - "description": "The unique, numeric id of this namespace.", - "type": "integer" - }, - "is_archived": { - "description": "Whether or not a namespace is archived.", - "type": "boolean" - }, - "owner": { - "description": "The user who owns this namespace", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] - }, - "subscription": { - "description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.", - "allOf": [ - { - "$ref": "#/definitions/models.Subscription" - } - ] - }, - "title": { - "description": "The name of this namespace.", - "type": "string", - "maxLength": 250, - "minLength": 1 - }, - "updated": { - "description": "A timestamp when this namespace was last updated. You cannot change this value.", - "type": "string" -<<<<<<< HEAD - }, - "web.CRUDable": {}, - "web.Rights": {} ->>>>>>> 4567a680... do the swag -======= - } ->>>>>>> 85307ce6... add swagger files } }, "models.ProjectUser": { @@ -7983,67 +7778,6 @@ const docTemplate = `{ } } }, -<<<<<<< HEAD -======= - "models.NamespaceWithLists": { - "type": "object", - "properties": { - "created": { - "description": "A timestamp when this namespace was created. You cannot change this value.", - "type": "string" - }, - "description": { - "description": "The description of the namespace", - "type": "string" - }, - "hex_color": { - "description": "The hex color of this namespace", - "type": "string", - "maxLength": 6 - }, - "id": { - "description": "The unique, numeric id of this namespace.", - "type": "integer" - }, - "is_archived": { - "description": "Whether or not a namespace is archived.", - "type": "boolean" - }, - "lists": { - "type": "array", - "items": { - "$ref": "#/definitions/models.List" - } - }, - "owner": { - "description": "The user who owns this namespace", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] - }, - "subscription": { - "description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.", - "allOf": [ - { - "$ref": "#/definitions/models.Subscription" - } - ] - }, - "title": { - "description": "The name of this namespace.", - "type": "string", - "maxLength": 250, - "minLength": 1 - }, - "updated": { - "description": "A timestamp when this namespace was last updated. You cannot change this value.", - "type": "string" - } - } - }, ->>>>>>> 4567a680... do the swag "models.RelatedTaskMap": { "type": "object", "additionalProperties": { @@ -8053,10 +7787,6 @@ const docTemplate = `{ } } }, -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 85307ce6... add swagger files "models.RelationKind": { "type": "string", "enum": [ @@ -8088,7 +7818,6 @@ const docTemplate = `{ "RelationKindCopiedTo" ] }, -<<<<<<< HEAD "models.ReminderRelation": { "type": "string", "enum": [ @@ -8102,8 +7831,6 @@ const docTemplate = `{ "ReminderRelationEndDate" ] }, -======= ->>>>>>> 85307ce6... add swagger files "models.Right": { "type": "integer", "enum": [ @@ -8117,7 +7844,6 @@ const docTemplate = `{ "RightAdmin" ] }, -<<<<<<< HEAD "models.RouteDetail": { "type": "object", "properties": { @@ -8129,10 +7855,6 @@ const docTemplate = `{ } } }, -======= ->>>>>>> 4567a680... do the swag -======= ->>>>>>> 85307ce6... add swagger files "models.SavedFilter": { "type": "object", "properties": { @@ -8358,7 +8080,7 @@ const docTemplate = `{ "type": "string" }, "subscription": { - "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.", + "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retrieving one task.", "allOf": [ { "$ref": "#/definitions/models.Subscription" @@ -8508,8 +8230,6 @@ const docTemplate = `{ } } }, -<<<<<<< HEAD -<<<<<<< HEAD "models.TaskReminder": { "type": "object", "properties": { @@ -8531,8 +8251,6 @@ const docTemplate = `{ } } }, -======= ->>>>>>> 85307ce6... add swagger files "models.TaskRepeatMode": { "type": "integer", "enum": [ @@ -8546,11 +8264,6 @@ const docTemplate = `{ "TaskRepeatModeFromCurrentDate" ] }, -<<<<<<< HEAD -======= ->>>>>>> 4567a680... do the swag -======= ->>>>>>> 85307ce6... add swagger files "models.Team": { "type": "object", "properties": { @@ -8598,40 +8311,6 @@ const docTemplate = `{ } } }, -<<<<<<< HEAD -======= - "models.TeamList": { - "type": "object", - "properties": { - "created": { - "description": "A timestamp when this relation was created. You cannot change this value.", - "type": "string" - }, - "id": { - "description": "The unique, numeric id of this list \u003c-\u003e team relation.", - "type": "integer" - }, - "right": { - "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "default": 0, - "maximum": 2, - "allOf": [ - { - "$ref": "#/definitions/models.Right" - } - ] - }, - "team_id": { - "description": "The team id.", - "type": "integer" - }, - "updated": { - "description": "A timestamp when this relation was last updated. You cannot change this value.", - "type": "string" - } - } - }, ->>>>>>> 4567a680... do the swag "models.TeamMember": { "type": "object", "properties": { diff --git a/pkg/swagger/swagger.json b/pkg/swagger/swagger.json index f3ab167d3..dcb4d07d9 100644 --- a/pkg/swagger/swagger.json +++ b/pkg/swagger/swagger.json @@ -7279,14 +7279,14 @@ "type": "integer", "minimum": 0 }, - "list_id": { - "description": "The list this bucket belongs to.", - "type": "integer" - }, "position": { "description": "The position this bucket has when querying all buckets. See the tasks.position property on how to use this.", "type": "number" }, + "project_id": { + "description": "The project this bucket belongs to.", + "type": "integer" + }, "tasks": { "description": "All tasks which belong to this bucket.", "type": "array", @@ -7454,7 +7454,7 @@ "type": "string" }, "subscription": { - "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.", + "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retrieving one task.", "allOf": [ { "$ref": "#/definitions/models.Subscription" @@ -7596,7 +7596,7 @@ "type": "string" }, "right": { - "description": "The right this list is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", + "description": "The right this project is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", "default": 0, "maximum": 2, "allOf": [ @@ -7606,7 +7606,7 @@ ] }, "shared_by": { - "description": "The user who shared this list", + "description": "The user who shared this project", "allOf": [ { "$ref": "#/definitions/user.User" @@ -7688,7 +7688,7 @@ "type": "boolean" }, "owner": { - "description": "The user who created this list.", + "description": "The user who created this project.", "allOf": [ { "$ref": "#/definitions/user.User" @@ -7703,7 +7703,7 @@ "type": "number" }, "subscription": { - "description": "The subscription status for the user reading this list. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one list.", + "description": "The subscription status for the user reading this project. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one project.", "allOf": [ { "$ref": "#/definitions/models.Subscription" @@ -7722,115 +7722,23 @@ } } }, - "models.ListDuplicate": { + "models.ProjectDuplicate": { "type": "object", "properties": { - "list": { - "description": "The copied list", + "duplicated_project": { + "description": "The copied project", "allOf": [ { - "$ref": "#/definitions/models.List" + "$ref": "#/definitions/models.Project" } ] }, - "namespace_id": { - "description": "The target namespace ID", + "parent_project_id": { + "description": "The target parent project", "type": "integer" } } }, - "models.ListUser": { - "type": "object", - "properties": { - "created": { - "description": "A timestamp when this relation was created. You cannot change this value.", - "type": "string" - }, - "id": { - "description": "The unique, numeric id of this list \u003c-\u003e user relation.", - "type": "integer" - }, - "right": { - "description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "default": 0, - "maximum": 2, - "allOf": [ - { - "$ref": "#/definitions/models.Right" - } - ] - }, - "updated": { - "description": "A timestamp when this relation was last updated. You cannot change this value.", - "type": "string" - }, - "user_id": { - "description": "The username.", - "type": "string" - } - } - }, - "models.Message": { - "type": "object", - "properties": { - "message": { - "description": "A standard message.", - "type": "string" - } - } - }, - "models.Namespace": { - "type": "object", - "properties": { - "created": { - "description": "A timestamp when this namespace was created. You cannot change this value.", - "type": "string" - }, - "description": { - "description": "The description of the namespace", - "type": "string" - }, - "hex_color": { - "description": "The hex color of this namespace", - "type": "string", - "maxLength": 6 - }, - "id": { - "description": "The unique, numeric id of this namespace.", - "type": "integer" - }, - "is_archived": { - "description": "Whether or not a namespace is archived.", - "type": "boolean" - }, - "owner": { - "description": "The user who owns this namespace", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] - }, - "subscription": { - "description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.", - "allOf": [ - { - "$ref": "#/definitions/models.Subscription" - } - ] - }, - "title": { - "description": "The name of this namespace.", - "type": "string", - "maxLength": 250, - "minLength": 1 - }, - "updated": { - "description": "A timestamp when this namespace was last updated. You cannot change this value.", - "type": "string" - } - } - }, "models.ProjectUser": { "type": "object", "properties": { @@ -7862,64 +7770,6 @@ } } }, - "models.NamespaceWithLists": { - "type": "object", - "properties": { - "created": { - "description": "A timestamp when this namespace was created. You cannot change this value.", - "type": "string" - }, - "description": { - "description": "The description of the namespace", - "type": "string" - }, - "hex_color": { - "description": "The hex color of this namespace", - "type": "string", - "maxLength": 6 - }, - "id": { - "description": "The unique, numeric id of this namespace.", - "type": "integer" - }, - "is_archived": { - "description": "Whether or not a namespace is archived.", - "type": "boolean" - }, - "lists": { - "type": "array", - "items": { - "$ref": "#/definitions/models.List" - } - }, - "owner": { - "description": "The user who owns this namespace", - "allOf": [ - { - "$ref": "#/definitions/user.User" - } - ] - }, - "subscription": { - "description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.", - "allOf": [ - { - "$ref": "#/definitions/models.Subscription" - } - ] - }, - "title": { - "description": "The name of this namespace.", - "type": "string", - "maxLength": 250, - "minLength": 1 - }, - "updated": { - "description": "A timestamp when this namespace was last updated. You cannot change this value.", - "type": "string" - } - } - }, "models.RelatedTaskMap": { "type": "object", "additionalProperties": { @@ -7960,6 +7810,19 @@ "RelationKindCopiedTo" ] }, + "models.ReminderRelation": { + "type": "string", + "enum": [ + "due_date", + "start_date", + "end_date" + ], + "x-enum-varnames": [ + "ReminderRelationDueDate", + "ReminderRelationStartDate", + "ReminderRelationEndDate" + ] + }, "models.Right": { "type": "integer", "enum": [ @@ -7973,6 +7836,17 @@ "RightAdmin" ] }, + "models.RouteDetail": { + "type": "object", + "properties": { + "method": { + "type": "string" + }, + "path": { + "type": "string" + } + } + }, "models.SavedFilter": { "type": "object", "properties": { @@ -8198,7 +8072,7 @@ "type": "string" }, "subscription": { - "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.", + "description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retrieving one task.", "allOf": [ { "$ref": "#/definitions/models.Subscription" @@ -8348,6 +8222,27 @@ } } }, + "models.TaskReminder": { + "type": "object", + "properties": { + "relative_period": { + "description": "A period in seconds relative to another date argument. Negative values mean the reminder triggers before the date. Default: 0, tiggers when RelativeTo is due.", + "type": "integer" + }, + "relative_to": { + "description": "The name of the date field to which the relative period refers to.", + "allOf": [ + { + "$ref": "#/definitions/models.ReminderRelation" + } + ] + }, + "reminder": { + "description": "The absolute time when the user wants to be reminded of the task.", + "type": "string" + } + } + }, "models.TaskRepeatMode": { "type": "integer", "enum": [ @@ -8408,37 +8303,6 @@ } } }, - "models.TeamList": { - "type": "object", - "properties": { - "created": { - "description": "A timestamp when this relation was created. You cannot change this value.", - "type": "string" - }, - "id": { - "description": "The unique, numeric id of this list \u003c-\u003e team relation.", - "type": "integer" - }, - "right": { - "description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.", - "default": 0, - "maximum": 2, - "allOf": [ - { - "$ref": "#/definitions/models.Right" - } - ] - }, - "team_id": { - "description": "The team id.", - "type": "integer" - }, - "updated": { - "description": "A timestamp when this relation was last updated. You cannot change this value.", - "type": "string" - } - } - }, "models.TeamMember": { "type": "object", "properties": { diff --git a/pkg/swagger/swagger.yaml b/pkg/swagger/swagger.yaml index b9116fa08..08eeb64f7 100644 --- a/pkg/swagger/swagger.yaml +++ b/pkg/swagger/swagger.yaml @@ -119,13 +119,13 @@ definitions: description: How many tasks can be at the same time on this board max minimum: 0 type: integer - list_id: - description: The list this bucket belongs to. - type: integer position: description: The position this bucket has when querying all buckets. See the tasks.position property on how to use this. type: number + project_id: + description: The project this bucket belongs to. + type: integer tasks: description: All tasks which belong to this bucket. items: @@ -384,7 +384,7 @@ definitions: shared_by: allOf: - $ref: '#/definitions/user.User' - description: The user who shared this list + description: The user who shared this project sharing_type: allOf: - $ref: '#/definitions/models.SharingType' @@ -452,7 +452,9 @@ definitions: owner: allOf: - $ref: '#/definitions/user.User' - description: The user who created this list. + description: The user who created this project. + parent_project_id: + type: integer position: description: The position this project has when querying all projects. See the tasks.position property on how to use this. @@ -473,85 +475,16 @@ definitions: this value. type: string type: object - models.ListDuplicate: + models.ProjectDuplicate: properties: - list: + duplicated_project: allOf: - - $ref: '#/definitions/models.List' - description: The copied list - namespace_id: - description: The target namespace ID + - $ref: '#/definitions/models.Project' + description: The copied project + parent_project_id: + description: The target parent project type: integer type: object - models.ListUser: - properties: - created: - description: A timestamp when this relation was created. You cannot change - this value. - type: string - id: - description: The unique, numeric id of this list <-> user relation. - type: integer - right: - allOf: - - $ref: '#/definitions/models.Right' - default: 0 - description: The right this user has. 0 = Read only, 1 = Read & Write, 2 = - Admin. See the docs for more details. - maximum: 2 - updated: - description: A timestamp when this relation was last updated. You cannot change - this value. - type: string - user_id: - description: The username. - type: string - type: object - models.Message: - properties: - message: - description: A standard message. - type: string - type: object - models.Namespace: - properties: - created: - description: A timestamp when this namespace was created. You cannot change - this value. - type: string - description: - description: The description of the namespace - type: string - hex_color: - description: The hex color of this namespace - maxLength: 6 - type: string - id: - description: The unique, numeric id of this namespace. - type: integer - is_archived: - description: Whether or not a namespace is archived. - type: boolean - owner: - allOf: - - $ref: '#/definitions/user.User' - description: The user who owns this namespace - subscription: - allOf: - - $ref: '#/definitions/models.Subscription' - description: |- - The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it. - Will only returned when retreiving one namespace. - title: - description: The name of this namespace. - maxLength: 250 - minLength: 1 - type: string - updated: - description: A timestamp when this namespace was last updated. You cannot - change this value. - type: string - type: object models.ProjectUser: properties: created: @@ -576,49 +509,6 @@ definitions: description: The username. type: string type: object - models.NamespaceWithLists: - properties: - created: - description: A timestamp when this namespace was created. You cannot change - this value. - type: string - description: - description: The description of the namespace - type: string - hex_color: - description: The hex color of this namespace - maxLength: 6 - type: string - id: - description: The unique, numeric id of this namespace. - type: integer - is_archived: - description: Whether or not a namespace is archived. - type: boolean - lists: - items: - $ref: '#/definitions/models.List' - type: array - owner: - allOf: - - $ref: '#/definitions/user.User' - description: The user who owns this namespace - subscription: - allOf: - - $ref: '#/definitions/models.Subscription' - description: |- - The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it. - Will only returned when retreiving one namespace. - title: - description: The name of this namespace. - maxLength: 250 - minLength: 1 - type: string - updated: - description: A timestamp when this namespace was last updated. You cannot - change this value. - type: string - type: object models.RelatedTaskMap: additionalProperties: items: @@ -653,6 +543,16 @@ definitions: - RelationKindFollows - RelationKindCopiedFrom - RelationKindCopiedTo + models.ReminderRelation: + enum: + - due_date + - start_date + - end_date + type: string + x-enum-varnames: + - ReminderRelationDueDate + - ReminderRelationStartDate + - ReminderRelationEndDate models.Right: enum: - 0 @@ -663,6 +563,13 @@ definitions: - RightRead - RightWrite - RightAdmin + models.RouteDetail: + properties: + method: + type: string + path: + type: string + type: object models.SavedFilter: properties: created: @@ -945,6 +852,22 @@ definitions: description: The ID of the "base" task, the task which has a relation to another. type: integer type: object + models.TaskReminder: + properties: + relative_period: + description: 'A period in seconds relative to another date argument. Negative + values mean the reminder triggers before the date. Default: 0, tiggers when + RelativeTo is due.' + type: integer + relative_to: + allOf: + - $ref: '#/definitions/models.ReminderRelation' + description: The name of the date field to which the relative period refers + to. + reminder: + description: The absolute time when the user wants to be reminded of the task. + type: string + type: object models.TaskRepeatMode: enum: - 0 @@ -990,30 +913,6 @@ definitions: this value. type: string type: object - models.TeamList: - properties: - created: - description: A timestamp when this relation was created. You cannot change - this value. - type: string - id: - description: The unique, numeric id of this list <-> team relation. - type: integer - right: - allOf: - - $ref: '#/definitions/models.Right' - default: 0 - description: The right this team has. 0 = Read only, 1 = Read & Write, 2 = - Admin. See the docs for more details. - maximum: 2 - team_id: - description: The team id. - type: integer - updated: - description: A timestamp when this relation was last updated. You cannot change - this value. - type: string - type: object models.TeamMember: properties: admin: -- 2.45.1 From 042f588001b6ef494c909e2dc8e3833c7cda9fd1 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Tue, 7 Nov 2023 15:24:23 +0100 Subject: [PATCH 73/93] fix typos --- pkg/models/error.go | 6 +++--- pkg/modules/auth/openid/openid.go | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/models/error.go b/pkg/models/error.go index 40a7b1c02..94de840e8 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1191,7 +1191,7 @@ func IsErrOIDCTeamDoesNotExist(err error) bool { // ErrTeamDoesNotExist represents an error where a team does not exist func (err ErrOIDCTeamDoesNotExist) Error() string { - return fmt.Sprintf("No Team with that name and valid oidcId could be found. [Team Name: %v] [OidcId : %v] ", err.Name, err.OidcID) + return fmt.Sprintf("No team with that name and valid oidcId could be found. [Team Name: %v] [OidcID : %v] ", err.Name, err.OidcID) } // ErrCodeTeamDoesNotExist holds the unique world-error code of this error @@ -1199,7 +1199,7 @@ const ErrCodeOIDCTeamDoesNotExist = 6008 // HTTPError holds the http error description func (err ErrOIDCTeamDoesNotExist) HTTPError() web.HTTPError { - return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No Team with that name and valid oidcId could be found."} + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No team with that name and valid oidcId could be found."} } // ErrOIDCTeamsDoNotExistForUser represents an error where an oidcTeam does not exist for the user @@ -1214,7 +1214,7 @@ func IsErrOIDCTeamsDoNotExistForUser(err error) bool { } func (err ErrOIDCTeamsDoNotExistForUser) Error() string { - return fmt.Sprintf("No Teams with property oidcId could be found for User [User ID: %d]", err.UserID) + return fmt.Sprintf("No teams with property oidcId could be found for user [User ID: %d]", err.UserID) } // ErrCodeTeamDoesNotExist holds the unique world-error code of this error diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 948d92d22..e7ad49841 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -211,7 +211,7 @@ func HandleCallback(c echo.Context) error { //find old teams for user through oidc oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) if err != nil { - log.Errorf("No Oidc Teams found for user %v", err) + log.Errorf("No oidc teams found for user %v", err) } oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) if err != nil { @@ -219,13 +219,13 @@ func HandleCallback(c echo.Context) error { } errs = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) for _, err := range errs { - log.Errorf("Found Error while signing out from teams %v", err) + log.Errorf("Found error while leaving teams %v", err) } } err = s.Commit() if err != nil { _ = s.Rollback() - log.Errorf("Error creating new Team for provider %s: %v", provider.Name, err) + log.Errorf("Error creating new team for provider %s: %v", provider.Name, err) return handler.HandleHTTPError(err, c) } // Create token @@ -331,7 +331,7 @@ func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.OIDCTeamD for _, oidcTeam := range teamData { team, err := models.GetTeamByOidcIDAndName(s, oidcTeam.OidcID, oidcTeam.TeamName) if err != nil { - log.Debugf("Team with oidc_id %v and name %v does not exist. Create Team.. ", oidcTeam.OidcID, oidcTeam.TeamName) + log.Debugf("Team with oidc_id %v and name %v does not exist. Creating team.. ", oidcTeam.OidcID, oidcTeam.TeamName) newTeam, err := CreateTeamWithData(s, oidcTeam, u) if err != nil { return te, err -- 2.45.1 From a7fa02a4d63e5db23cce8818a961c1a31a1ed1e3 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Tue, 7 Nov 2023 15:26:39 +0100 Subject: [PATCH 74/93] fix lint --- pkg/migration/20230104152903.go | 2 +- pkg/utils/slice_difference.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/migration/20230104152903.go b/pkg/migration/20230104152903.go index 8991ddd89..82747d5f4 100644 --- a/pkg/migration/20230104152903.go +++ b/pkg/migration/20230104152903.go @@ -1,5 +1,5 @@ // Vikunja is a to-do list application to facilitate your life. -// Copyright 2018-2021 Vikunja and contributors. All rights reserved. +// Copyright 2018-present Vikunja and contributors. All rights reserved. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public Licensee as published by diff --git a/pkg/utils/slice_difference.go b/pkg/utils/slice_difference.go index cc01fad10..68ae56bd4 100644 --- a/pkg/utils/slice_difference.go +++ b/pkg/utils/slice_difference.go @@ -1,5 +1,5 @@ // Vikunja is a to-do list application to facilitate your life. -// Copyright 2018-2021 Vikunja and contributors. All rights reserved. +// Copyright 2018-present Vikunja and contributors. All rights reserved. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public Licensee as published by -- 2.45.1 From bd66275acd88d6ad5de6ad64b74057ffd70f4a14 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Tue, 7 Nov 2023 15:27:10 +0100 Subject: [PATCH 75/93] tiny changes in openid.md --- docs/content/doc/setup/openid.md | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/docs/content/doc/setup/openid.md b/docs/content/doc/setup/openid.md index fd6487ebd..8a55697db 100644 --- a/docs/content/doc/setup/openid.md +++ b/docs/content/doc/setup/openid.md @@ -5,7 +5,7 @@ See below for setup instructions. To distinguish between teams created in Vikunja and teams generated automatically via oidc, generated teams have an `oidcID` assigned internally. -## Setup for atuhentik +## Setup for authentik To configure automatic team management through authentik, we assume you have already set up Authentik as an oidc provider for authentication with Vikunja. @@ -24,8 +24,9 @@ for group in request.user.ak_groups.all(): return groupsDict ``` -``` output example: + +``` { "vikunja_groups": [ { @@ -42,30 +43,26 @@ output example: Now when you log into Vikunja via oidc there will be a list of scopes you are claiming from your oidc provider. You should see the description you entered in the oidc provider's admin area. -Log in and go to teams. -You should see "(sso: XXXXX)" written next to each team you were asigned through oidc. +Proceed to vikunja and go to teams. +You should see "(sso: *your_oidcID*)" written next to each team you were asigned through oidc. -## IMPORTANT NOTES: -* **SSO/OIDC teams cannot be edited.** +## Important Notes: +* SSO/OIDC teams cannot be edited. -* **It is required to deliver the key "vikunja_groups" via your custom_scope since this is the key vikunja is looking for to start the procedure.** +* It is required to deliver the key "vikunja_groups" via your custom_scope since this is the key vikunja is looking for to start the procedure. -* **Additionally, make sure to deliver an "oidcID" and a "name" attribute in the oidc token.** +* Additionally, make sure to deliver an "oidcID" and a "name" attribute in the oidc token. - - ---- - -## BEHAVIOR +## Use cases *All examples assume one team called "team 1"* -1. *Token delivers team.name +team.oidcId and Vikunja team does not exist:* \ +1. *Token delivers team.name +team.oidc_id and Vikunja team does not exist:* \ New team will be created called "team 1" with attribute oidcId: "33929" 2. *In Vikunja Team with name "team 1" already exists in vikunja, but has no oidcID set:* \ -new team will be created called "team 1" with attribute oidcId: "33929" +new team will be created called "team 1" with attribute oidc_id: "33929" 3. *In Vikunja Team with name "team 1" already exists in vikunja, but has different oidcID set:* \ -- 2.45.1 From 29e53564773d77b7044bc37fa76e887a70cb2d6e Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 8 Nov 2023 12:40:18 +0100 Subject: [PATCH 76/93] use one sql query for removing user form team --- pkg/modules/auth/openid/openid.go | 39 ++++++++++++++----------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index e7ad49841..481de1047 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -211,14 +211,14 @@ func HandleCallback(c echo.Context) error { //find old teams for user through oidc oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) if err != nil { - log.Errorf("No oidc teams found for user %v", err) + log.Debugf("No oidc teams found for user %v", err) } oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) if err != nil { log.Errorf("Could not proceed with group routine %v", err) } - errs = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) - for _, err := range errs { + err = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + if err != nil { log.Errorf("Found error while leaving teams %v", err) } } @@ -257,26 +257,21 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models. return oidcTeams, err } -func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (errs []error) { - errs = []error{} - for _, teamID := range teamIDs { - tm := models.TeamMember{TeamID: teamID, UserID: u.ID, Username: u.Username} - exists, err := tm.CheckMembership(s) - if err != nil { - errs = append(errs, err) - continue - } - if !exists { - continue - } - err = tm.Delete(s, u) - // if you cannot delete the team_member - if err != nil { - errs = append(errs, err) - continue - } +func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (err error) { + + if len(teamIDs) < 1 { + return nil } - return errs + + strSlice := make([]string, len(teamIDs)) + for i, num := range teamIDs { + strSlice[i] = strconv.FormatInt(num, 10) + } + + log.Debugf("Removing team_member with user_id %v from team_ids %v", u.ID, strings.Join(strSlice, ",")) + + _, err = s.Where("team_id IN (?) AND user_id = ?", strings.Join(strSlice, ","), u.ID).Delete(&models.TeamMember{}) + return err } func getTeamDataFromToken(groups []map[string]interface{}, provider *Provider) (teamData []models.OIDCTeamData, errs []error) { -- 2.45.1 From 1ef77a1b195542e71b7807431d26c76949e683e7 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 8 Nov 2023 12:41:03 +0100 Subject: [PATCH 77/93] minor changes in teams.go and consistent attribute renaming in openid.md --- docs/content/doc/setup/openid.md | 10 +++++----- pkg/models/teams.go | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/content/doc/setup/openid.md b/docs/content/doc/setup/openid.md index 8a55697db..d9118f93f 100644 --- a/docs/content/doc/setup/openid.md +++ b/docs/content/doc/setup/openid.md @@ -57,20 +57,20 @@ You should see "(sso: *your_oidcID*)" written next to each team you were asigned *All examples assume one team called "team 1"* -1. *Token delivers team.name +team.oidc_id and Vikunja team does not exist:* \ -New team will be created called "team 1" with attribute oidcId: "33929" +1. *Token delivers team.name +team.oidcID and Vikunja team does not exist:* \ +New team will be created called "team 1" with attribute oidcID: "33929" 2. *In Vikunja Team with name "team 1" already exists in vikunja, but has no oidcID set:* \ -new team will be created called "team 1" with attribute oidc_id: "33929" +new team will be created called "team 1" with attribute oidcID: "33929" 3. *In Vikunja Team with name "team 1" already exists in vikunja, but has different oidcID set:* \ -new team will be created called "team 1" with attribute oidcId: "33929" +new team will be created called "team 1" with attribute oidcID: "33929" 4. *In Vikunja Team with oidcID "33929" already exists in vikunja, but has different name than "team1":* \ -new team will be created called "team 1" with attribute oidcId: "33929" +new team will be created called "team 1" with attribute oidcID: "33929" 5. *Scope vikunja_scope is not set:* \ diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 7ccbe560a..7a78d7014 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -136,8 +136,6 @@ func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (*T has, err := s. Table("teams"). Where("oidc_id = ? AND name = ?", oidcID, teamName). - Asc("id"). - Limit(1). Get(team) if !has || err != nil { return nil, ErrOIDCTeamDoesNotExist{teamName, oidcID} -- 2.45.1 From c283e876b0eb5adc261f172209dc5dabd4b872c4 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 8 Nov 2023 14:50:14 +0100 Subject: [PATCH 78/93] delete sso teams on login if empty --- pkg/modules/auth/openid/openid.go | 16 ++++++++++++++-- pkg/utils/slice_difference.go | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 481de1047..d1f09afaa 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -217,10 +217,12 @@ func HandleCallback(c echo.Context) error { if err != nil { log.Errorf("Could not proceed with group routine %v", err) } - err = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams)) + teamIDsToLeave := utils.NotIn(oldOidcTeams, oidcTeams) + err = RemoveUserFromTeamsByIds(s, u, teamIDsToLeave) if err != nil { log.Errorf("Found error while leaving teams %v", err) } + err = RemoveEmptySSOTeams(s, u, teamIDsToLeave) } err = s.Commit() if err != nil { @@ -257,6 +259,17 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models. return oidcTeams, err } +func RemoveEmptySSOTeams(s *xorm.Session, u *user.User, teamIDs []int64) (err error) { + for _, teamID := range teamIDs { + count, err := s.Where("team_id = ?", teamID).Count(&models.TeamMember{}) + if count == 0 && err == nil { + log.Debugf("SSO team with id %v has no members. It will be deleted", teamID) + _, err = s.Where("id = ?", teamID).Delete(&models.Team{}) + } + } + return err +} + func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (err error) { if len(teamIDs) < 1 { @@ -269,7 +282,6 @@ func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (e } log.Debugf("Removing team_member with user_id %v from team_ids %v", u.ID, strings.Join(strSlice, ",")) - _, err = s.Where("team_id IN (?) AND user_id = ?", strings.Join(strSlice, ","), u.ID).Delete(&models.TeamMember{}) return err } diff --git a/pkg/utils/slice_difference.go b/pkg/utils/slice_difference.go index 68ae56bd4..fa3323407 100644 --- a/pkg/utils/slice_difference.go +++ b/pkg/utils/slice_difference.go @@ -16,7 +16,7 @@ package utils -// find the elements which appear in slice1,but not in slice2 +// find the elements which appear in slice1, but not in slice2 func NotIn(slice1 []int64, slice2 []int64) []int64 { var diff []int64 -- 2.45.1 From c6100ceb5aba4568e868e513d8c314641f89c0a7 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 8 Nov 2023 16:58:56 +0100 Subject: [PATCH 79/93] tests and fixes --- pkg/db/fixtures/team_members.yml | 4 + pkg/db/fixtures/teams.yml | 6 +- pkg/models/teams.go | 2 +- pkg/modules/auth/openid/openid.go | 4 +- pkg/modules/auth/openid/openid_test.go | 138 ++++++++++++++++++++++++- 5 files changed, 150 insertions(+), 4 deletions(-) diff --git a/pkg/db/fixtures/team_members.yml b/pkg/db/fixtures/team_members.yml index eb671be41..889322b7b 100644 --- a/pkg/db/fixtures/team_members.yml +++ b/pkg/db/fixtures/team_members.yml @@ -55,3 +55,7 @@ team_id: 13 user_id: 10 created: 2018-12-01 15:13:12 +- + team_id: 14 + user_id: 10 + created: 2018-12-01 15:13:12 \ No newline at end of file diff --git a/pkg/db/fixtures/teams.yml b/pkg/db/fixtures/teams.yml index b7d347df4..defdedd62 100644 --- a/pkg/db/fixtures/teams.yml +++ b/pkg/db/fixtures/teams.yml @@ -28,4 +28,8 @@ created_by_id: 7 - id: 13 name: testteam13 - created_by_id: 7 \ No newline at end of file + created_by_id: 7 +- id: 14 + name: testteam14 + created_by_id: 7 + oidc_id: 14 \ No newline at end of file diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 7a78d7014..189250a90 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -152,7 +152,7 @@ func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err e Cols("teams.id"). Find(&ts) if ts == nil || err != nil { - return ts, ErrOIDCTeamsDoNotExistForUser{userID} + return ts, err } return ts, nil } diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index d1f09afaa..50970741f 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -98,6 +98,7 @@ func HandleCallback(c echo.Context) error { // Check if the provider exists providerKey := c.Param("provider") provider, err := GetProvider(providerKey) + log.Debugf("Provider: %v", provider) if err != nil { log.Error(err) return handler.HandleHTTPError(err, c) @@ -202,8 +203,9 @@ func HandleCallback(c echo.Context) error { } // does the oidc token contain well formed "vikunja_groups" through vikunja_scope + log.Debugf("Checking for vikunja_groups in token %v", cl.VikunjaGroups) teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, provider) - if teamData != nil { + if teamData != nil && len(teamData) > 0 { for _, err := range errs { log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) } diff --git a/pkg/modules/auth/openid/openid_test.go b/pkg/modules/auth/openid/openid_test.go index 18da67eb7..8f68ad791 100644 --- a/pkg/modules/auth/openid/openid_test.go +++ b/pkg/modules/auth/openid/openid_test.go @@ -20,7 +20,9 @@ import ( "testing" "code.vikunja.io/api/pkg/db" - + "code.vikunja.io/api/pkg/models" + "code.vikunja.io/api/pkg/user" + "code.vikunja.io/api/pkg/utils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -95,4 +97,138 @@ func TestGetOrCreateUser(t *testing.T) { "email": cl.Email, }, false) }) + t.Run("existing user, non existing team", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + team := "new sso team" + oidcID := "47404" + cl := &claims{ + Email: "other-email-address@some.service.com", + VikunjaGroups: []map[string]interface{}{ + {"name": team, "oidcID": oidcID}, + }, + } + + u, err := getOrCreateUser(s, cl, "https://some.service.com", "12345") + assert.NoError(t, err) + teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, nil) + for _, err := range errs { + assert.NoError(t, err) + } + assert.NoError(t, err) + oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) + assert.NoError(t, err) + err = s.Commit() + assert.NoError(t, err) + + db.AssertExists(t, "users", map[string]interface{}{ + "id": u.ID, + "email": cl.Email, + }, false) + db.AssertExists(t, "teams", map[string]interface{}{ + "id": oidcTeams, + "name": team, + }, false) + }) + + t.Run("existing user, assign to existing team", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + team := "testteam14" + oidcID := "14" + cl := &claims{ + Email: "other-email-address@some.service.com", + VikunjaGroups: []map[string]interface{}{ + {"name": team, "oidcID": oidcID}, + }, + } + + u := &user.User{ID: 10} + teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, nil) + for _, err := range errs { + assert.NoError(t, err) + } + oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) + assert.NoError(t, err) + err = s.Commit() + assert.NoError(t, err) + + db.AssertExists(t, "team_members", map[string]interface{}{ + "team_id": oidcTeams, + "user_id": u.ID, + }, false) + }) + t.Run("existing user, remove from existing team", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + cl := &claims{ + Email: "other-email-address@some.service.com", + VikunjaGroups: []map[string]interface{}{}, + } + + u := &user.User{ID: 10} + teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, nil) + if len(errs) > 0 { + for _, err := range errs { + assert.NoError(t, err) + } + } + oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) + assert.NoError(t, err) + oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) + assert.NoError(t, err) + teamIDsToLeave := utils.NotIn(oldOidcTeams, oidcTeams) + assert.NoError(t, err) + err = RemoveUserFromTeamsByIds(s, u, teamIDsToLeave) + assert.NoError(t, err) + // err = RemoveEmptySSOTeams(s, u, teamIDsToLeave) + // assert.NoError(t, err) + err = s.Commit() + assert.NoError(t, err) + + db.AssertMissing(t, "team_members", map[string]interface{}{ + "team_id": oidcTeams, + "user_id": u.ID, + }) + }) + t.Run("existing user, remove from existing team and delete team", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + cl := &claims{ + Email: "other-email-address@some.service.com", + VikunjaGroups: []map[string]interface{}{}, + } + + u := &user.User{ID: 10} + teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, nil) + if len(errs) > 0 { + for _, err := range errs { + assert.NoError(t, err) + } + } + oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) + assert.NoError(t, err) + oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) + assert.NoError(t, err) + teamIDsToLeave := utils.NotIn(oldOidcTeams, oidcTeams) + assert.NoError(t, err) + err = RemoveUserFromTeamsByIds(s, u, teamIDsToLeave) + assert.NoError(t, err) + err = RemoveEmptySSOTeams(s, u, teamIDsToLeave) + assert.NoError(t, err) + err = s.Commit() + assert.NoError(t, err) + + db.AssertMissing(t, "teams", map[string]interface{}{ + "id": oidcTeams, + }) + }) } -- 2.45.1 From aaa090f6bb93ae5909ced75c87426ec99a3c36f4 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 30 Nov 2023 14:40:12 +0100 Subject: [PATCH 80/93] fix lint and add test --- pkg/modules/auth/openid/openid.go | 18 +++++++++++++----- pkg/modules/auth/openid/openid_test.go | 17 ++++++++++++----- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 50970741f..fbcfa5f73 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -205,7 +205,7 @@ func HandleCallback(c echo.Context) error { // does the oidc token contain well formed "vikunja_groups" through vikunja_scope log.Debugf("Checking for vikunja_groups in token %v", cl.VikunjaGroups) teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, provider) - if teamData != nil && len(teamData) > 0 { + if len(teamData) > 0 { for _, err := range errs { log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err) } @@ -224,7 +224,12 @@ func HandleCallback(c echo.Context) error { if err != nil { log.Errorf("Found error while leaving teams %v", err) } - err = RemoveEmptySSOTeams(s, u, teamIDsToLeave) + errors := RemoveEmptySSOTeams(s, teamIDsToLeave) + if len(errors) > 0 { + for _, err := range errors { + log.Errorf("Found error while removing empty teams %v", err) + } + } } err = s.Commit() if err != nil { @@ -261,15 +266,18 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models. return oidcTeams, err } -func RemoveEmptySSOTeams(s *xorm.Session, u *user.User, teamIDs []int64) (err error) { +func RemoveEmptySSOTeams(s *xorm.Session, teamIDs []int64) (errs []error) { for _, teamID := range teamIDs { count, err := s.Where("team_id = ?", teamID).Count(&models.TeamMember{}) if count == 0 && err == nil { log.Debugf("SSO team with id %v has no members. It will be deleted", teamID) - _, err = s.Where("id = ?", teamID).Delete(&models.Team{}) + _, _err := s.Where("id = ?", teamID).Delete(&models.Team{}) + if _err != nil { + errs = append(errs, _err) + } } } - return err + return errs } func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (err error) { diff --git a/pkg/modules/auth/openid/openid_test.go b/pkg/modules/auth/openid/openid_test.go index 8f68ad791..bff4d149f 100644 --- a/pkg/modules/auth/openid/openid_test.go +++ b/pkg/modules/auth/openid/openid_test.go @@ -187,8 +187,14 @@ func TestGetOrCreateUser(t *testing.T) { assert.NoError(t, err) err = RemoveUserFromTeamsByIds(s, u, teamIDsToLeave) assert.NoError(t, err) - // err = RemoveEmptySSOTeams(s, u, teamIDsToLeave) - // assert.NoError(t, err) + errs = RemoveEmptySSOTeams(s, teamIDsToLeave) + for _, err = range errs { + assert.NoError(t, err) + } + errs = RemoveEmptySSOTeams(s, teamIDsToLeave) + for _, err = range errs { + assert.NoError(t, err) + } err = s.Commit() assert.NoError(t, err) @@ -222,11 +228,12 @@ func TestGetOrCreateUser(t *testing.T) { assert.NoError(t, err) err = RemoveUserFromTeamsByIds(s, u, teamIDsToLeave) assert.NoError(t, err) - err = RemoveEmptySSOTeams(s, u, teamIDsToLeave) - assert.NoError(t, err) + errs = RemoveEmptySSOTeams(s, teamIDsToLeave) + for _, err := range errs { + assert.NoError(t, err) + } err = s.Commit() assert.NoError(t, err) - db.AssertMissing(t, "teams", map[string]interface{}{ "id": oidcTeams, }) -- 2.45.1 From 48ba08322668d9d88684f9724dfc0801c35ca73d Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 1 Dec 2023 15:53:01 +0100 Subject: [PATCH 81/93] docs: expand openid docs --- docs/content/doc/setup/openid.md | 55 ++++++++++++++++---------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/docs/content/doc/setup/openid.md b/docs/content/doc/setup/openid.md index d9118f93f..e02047fa6 100644 --- a/docs/content/doc/setup/openid.md +++ b/docs/content/doc/setup/openid.md @@ -1,21 +1,33 @@ -# Assign teams via oidc -Vikunja is capable of automatically adding users to a team based on a group defined in the oidc provider. If used, Vikunja will sync teams, automatically create new ones and make sure the members are part of the configured teams. Teams which only exist because they are generated from oidc attributes are not configurable in Vikunja. +# OpenID -See below for setup instructions. +Vikunja allows for authentication with an oauth provider via the OpenID standard. + +To learn more about how to configure this, [check out the examples]({{< ref "openid-examples.md">}}) + +{{< table_of_contents >}} + +## Automatically assign users to teams + +Vikunja is capable of automatically adding users to a team based on a group defined in the oidc provider. +If configured, Vikunja will sync teams, automatically create new ones and make sure the members are part of the configured teams. +Teams which exist only because they were created from oidc attributes are not editable in Vikunja. To distinguish between teams created in Vikunja and teams generated automatically via oidc, generated teams have an `oidcID` assigned internally. -## Setup for authentik +You need to make sure the OpenID provider has the `vikunja_groups` scope via your custom scope since this is the key Vikunja is looking for to start the procedure. -To configure automatic team management through authentik, we assume you have already set up Authentik as an oidc provider for authentication with Vikunja. +Additionally, make sure to deliver an `oidcID` and a `name` attribute in the oidc token. + +### Setup in Authentik + +To configure automatic team management through Authentik, we assume you have already [set up Authentik]({{< ref "openid-examples.md">}}#authentik) as an oidc provider for authentication with Vikunja. To use Authentik's group assignment feature, follow these steps: -1. Edit [config.yml](https://kolaente.dev/vikunja/api/src/branch/main/config.yml.sample) to include scope: `openid profile email vikunja_scope` +1. Edit [your config]({{< ref "config.md">}}) to include the following scopes: `openid profile email vikunja_scope` 2. Open `/if/admin/#/core/property-mappings` 3. Create a new mapping called `vikunja_scope`. There is a field to enter python expressions that will be delivered with the oidc token. -4. Write a small script like this to add group information to `vikunja_scope`: - +4. Write a small script like the following to add group information to `vikunja_scope`: ```python groupsDict = {"vikunja_groups": []} @@ -40,43 +52,32 @@ output example: ] } ``` -Now when you log into Vikunja via oidc there will be a list of scopes you are claiming from your oidc provider. -You should see the description you entered in the oidc provider's admin area. -Proceed to vikunja and go to teams. -You should see "(sso: *your_oidcID*)" written next to each team you were asigned through oidc. +Now when you log into Vikunja via Authentik it will show you a list of scopes you are claiming. +You should see the description you entered on the oidc provider's admin area. -## Important Notes: -* SSO/OIDC teams cannot be edited. - -* It is required to deliver the key "vikunja_groups" via your custom_scope since this is the key vikunja is looking for to start the procedure. - -* Additionally, make sure to deliver an "oidcID" and a "name" attribute in the oidc token. +Proceed to vikunja and open the teams page in the sidebar menu. +You should see "(sso: *your_oidcID*)" written next to each team you were assigned through oidc. ## Use cases -*All examples assume one team called "team 1"* - -1. *Token delivers team.name +team.oidcID and Vikunja team does not exist:* \ -New team will be created called "team 1" with attribute oidcID: "33929" +All examples assume one team called "Team 1" in your provider. +* *Token delivers team.name +team.oidcID and Vikunja team does not exist:* \ +New team will be created called "Team 1" with attribute oidcID: "33929" 2. *In Vikunja Team with name "team 1" already exists in vikunja, but has no oidcID set:* \ new team will be created called "team 1" with attribute oidcID: "33929" - 3. *In Vikunja Team with name "team 1" already exists in vikunja, but has different oidcID set:* \ new team will be created called "team 1" with attribute oidcID: "33929" - 4. *In Vikunja Team with oidcID "33929" already exists in vikunja, but has different name than "team1":* \ new team will be created called "team 1" with attribute oidcID: "33929" - 5. *Scope vikunja_scope is not set:* \ nothing happens - 6. *oidcID is not set:* \ You'll get error. Custom Scope malformed @@ -87,4 +88,4 @@ You will stay in team 3 since it was not set by the oidc provider 8. *In Vikunja I am in "team 3" with oidcID "12345", but the token does not deliver any data for "team 3"*:\ You will be signed out of all teams, which have an oidcID set and are not contained in the token. -Especially if you've been the last team member, the team will be deleted. \ No newline at end of file +Especially if you've been the last team member, the team will be deleted. -- 2.45.1 From 7011df887678f6923c064fbce769d46eb8e5596f Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 1 Dec 2023 15:55:56 +0100 Subject: [PATCH 82/93] chore: refactor --- pkg/models/team_members.go | 5 ++--- pkg/modules/auth/openid/openid.go | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pkg/models/team_members.go b/pkg/models/team_members.go index 9bcd06426..a06cf83db 100644 --- a/pkg/models/team_members.go +++ b/pkg/models/team_members.go @@ -108,11 +108,10 @@ func (tm *TeamMember) Delete(s *xorm.Session, _ web.Auth) (err error) { return } -func (tm *TeamMember) CheckMembership(s *xorm.Session) (exists bool, err error) { - exists, err = s. +func (tm *TeamMember) MembershipExists(s *xorm.Session) (exists bool, err error) { + return s. Where("team_id = ? AND user_id = ?", tm.TeamID, tm.UserID). Exist(&TeamMember{}) - return exists, err } // Update toggles a team member's admin status diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index fbcfa5f73..5f37f5c52 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -254,7 +254,7 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models. } for _, team := range teams { tm := models.TeamMember{TeamID: team.ID, UserID: u.ID, Username: u.Username} - exists, _ := tm.CheckMembership(s) + exists, _ := tm.MembershipExists(s) if !exists { err = tm.Create(s, u) if err != nil { -- 2.45.1 From ec39d9f02aee51353cf328c0485122e2b423f2a5 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Wed, 6 Dec 2023 14:43:56 +0100 Subject: [PATCH 83/93] tiny changes in openid.go, revert error.go, link to docs --- config.yml.sample | 4 ++-- pkg/models/error.go | 2 +- pkg/modules/auth/openid/openid.go | 18 ++++++++---------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/config.yml.sample b/config.yml.sample index d0f9db6d1..1d42b05c0 100644 --- a/config.yml.sample +++ b/config.yml.sample @@ -203,7 +203,7 @@ ratelimit: # Possible values are "keyvalue", "memory" or "redis". # When choosing "keyvalue" this setting follows the one configured in the "keyvalue" section. store: keyvalue - # The number of requests a user can make from the same IP to all unauthenticated routes (login, register, + # The number of requests a user can make from the same IP to all unauthenticated routes (login, register, # password confirmation, email verification, password reset request) per minute. This limit cannot be disabled. # You should only change this if you know what you're doing. noauthlimit: 10 @@ -326,7 +326,7 @@ auth: # The client secret used to authenticate Vikunja at the OpenID Connect provider. clientsecret: # The scope necessary to use oidc. - # If you want to use the Feature to create and assign to vikunja teams via oidc, you have to add the custom "vikunja_scope" and check [openid.md](https://kolaente.dev/vikunja/api/src/branch/main/pkg/modules/auth/openid/openid.md) + # If you want to use the Feature to create and assign to vikunja teams via oidc, you have to add the custom "vikunja_scope" and check [openid.md](https://vikunja.io/docs/openid/) # e.g. scope: openid email profile vikunja_scope scope: openid email profile diff --git a/pkg/models/error.go b/pkg/models/error.go index 94de840e8..2e31a6e58 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -1081,7 +1081,7 @@ func (err ErrTeamDoesNotExist) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "This team does not exist."} } -// ErrTeamAlreadyHasAccess represents an error where a team already has access to a list/namespace +// ErrTeamAlreadyHasAccess represents an error where a team already has access to a project type ErrTeamAlreadyHasAccess struct { TeamID int64 ID int64 diff --git a/pkg/modules/auth/openid/openid.go b/pkg/modules/auth/openid/openid.go index 5f37f5c52..1f80445cc 100644 --- a/pkg/modules/auth/openid/openid.go +++ b/pkg/modules/auth/openid/openid.go @@ -286,13 +286,8 @@ func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (e return nil } - strSlice := make([]string, len(teamIDs)) - for i, num := range teamIDs { - strSlice[i] = strconv.FormatInt(num, 10) - } - - log.Debugf("Removing team_member with user_id %v from team_ids %v", u.ID, strings.Join(strSlice, ",")) - _, err = s.Where("team_id IN (?) AND user_id = ?", strings.Join(strSlice, ","), u.ID).Delete(&models.TeamMember{}) + log.Debugf("Removing team_member with user_id %v from team_ids %v", u.ID, teamIDs) + _, err = s.In("team_id", teamIDs).And("user_id = ?", u.ID).Delete(&models.TeamMember{}) return err } @@ -303,13 +298,16 @@ func getTeamDataFromToken(groups []map[string]interface{}, provider *Provider) ( var name string var description string var oidcID string - if team["name"] != nil { + _, exists := team["name"] + if exists { name = team["name"].(string) } - if team["description"] != nil { + _, exists = team["description"] + if exists { description = team["description"].(string) } - if team["oidcID"] != nil { + _, exists = team["oidcID"] + if exists { switch t := team["oidcID"].(type) { case int64: oidcID = strconv.FormatInt(team["oidcID"].(int64), 10) -- 2.45.1 From 85406f6847ba9ee2490374dba528bfe0d79475b2 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 23 Feb 2024 12:39:03 +0100 Subject: [PATCH 84/93] adding authentik setup to openid-examples, some work in documentation --- config.yml.sample | 2 +- docs/content/doc/setup/config.md | 8 ++++---- docs/content/doc/setup/openid-examples.md | 2 +- docs/content/doc/setup/openid.md | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/config.yml.sample b/config.yml.sample index 1d42b05c0..19a3feb11 100644 --- a/config.yml.sample +++ b/config.yml.sample @@ -326,7 +326,7 @@ auth: # The client secret used to authenticate Vikunja at the OpenID Connect provider. clientsecret: # The scope necessary to use oidc. - # If you want to use the Feature to create and assign to vikunja teams via oidc, you have to add the custom "vikunja_scope" and check [openid.md](https://vikunja.io/docs/openid/) + # If you want to use the Feature to create and assign to vikunja teams via oidc, you have to add the custom "vikunja_scope" and check [openid.md](https://vikunja.io/docs/openid/). # e.g. scope: openid email profile vikunja_scope scope: openid email profile diff --git a/docs/content/doc/setup/config.md b/docs/content/doc/setup/config.md index a24236524..6b64227c7 100644 --- a/docs/content/doc/setup/config.md +++ b/docs/content/doc/setup/config.md @@ -94,7 +94,7 @@ Environment path: `VIKUNJA_SERVICE_JWTTTL` ### jwtttllong -The duration of the "remember me" time in seconds. When the login request is made with +The duration of the "remember me" time in seconds. When the login request is made with the long param set, the token returned will be valid for this period. The default is 2592000 seconds (30 Days). @@ -289,7 +289,7 @@ Environment path: `VIKUNJA_SERVICE_ENABLEEMAILREMINDERS` ### enableuserdeletion -If true, will allow users to request the complete deletion of their account. When using external authentication methods +If true, will allow users to request the complete deletion of their account. When using external authentication methods it may be required to coordinate with them in order to delete the account. This setting will not affect the cli commands for user deletion. @@ -569,7 +569,7 @@ Environment path: `VIKUNJA_DATABASE_TLS` Whether to enable the Typesense integration. If true, all tasks will be synced to the configured Typesense instance and all search and filtering will run through Typesense instead of only through the database. -Typesense allows fast fulltext search including fuzzy matching support. It may return different results than +Typesense allows fast fulltext search including fuzzy matching support. It may return different results than what you'd get with a database-only search. Default: `false` @@ -1024,7 +1024,7 @@ Environment path: `VIKUNJA_RATELIMIT_STORE` ### noauthlimit -The number of requests a user can make from the same IP to all unauthenticated routes (login, register, +The number of requests a user can make from the same IP to all unauthenticated routes (login, register, password confirmation, email verification, password reset request) per minute. This limit cannot be disabled. You should only change this if you know what you're doing. diff --git a/docs/content/doc/setup/openid-examples.md b/docs/content/doc/setup/openid-examples.md index 3f7d37ca6..dd3165b79 100644 --- a/docs/content/doc/setup/openid-examples.md +++ b/docs/content/doc/setup/openid-examples.md @@ -67,7 +67,7 @@ Google config: Note that there currently seems to be no way to stop creation of new users, even when `enableregistration` is `false` in the configuration. This means that this approach works well only with an "Internal Organization" app for Google Workspace, which limits the allowed users to organizational accounts only. External / public applications will potentially allow every Google user to register. -## Keycloak +## Keycloak Vikunja Config: ```yaml diff --git a/docs/content/doc/setup/openid.md b/docs/content/doc/setup/openid.md index e02047fa6..7e257996f 100644 --- a/docs/content/doc/setup/openid.md +++ b/docs/content/doc/setup/openid.md @@ -8,13 +8,13 @@ To learn more about how to configure this, [check out the examples]({{< ref "ope ## Automatically assign users to teams -Vikunja is capable of automatically adding users to a team based on a group defined in the oidc provider. -If configured, Vikunja will sync teams, automatically create new ones and make sure the members are part of the configured teams. +Vikunja is capable of automatically adding users to a team based on a group defined in the oidc provider. +If configured, Vikunja will sync teams, automatically create new ones and make sure the members are part of the configured teams. Teams which exist only because they were created from oidc attributes are not editable in Vikunja. To distinguish between teams created in Vikunja and teams generated automatically via oidc, generated teams have an `oidcID` assigned internally. -You need to make sure the OpenID provider has the `vikunja_groups` scope via your custom scope since this is the key Vikunja is looking for to start the procedure. +You need to make sure the OpenID provider has the `vikunja_groups` scope via your custom scope since this is the key, which is looked up by Vikunja to start the procedure. Additionally, make sure to deliver an `oidcID` and a `name` attribute in the oidc token. @@ -26,7 +26,7 @@ To use Authentik's group assignment feature, follow these steps: 1. Edit [your config]({{< ref "config.md">}}) to include the following scopes: `openid profile email vikunja_scope` 2. Open `/if/admin/#/core/property-mappings` -3. Create a new mapping called `vikunja_scope`. There is a field to enter python expressions that will be delivered with the oidc token. +3. Create a new property mapping called `vikunja_scope` as scope mapping. There is a field `expression` to enter python expressions that will be delivered with the oidc token. 4. Write a small script like the following to add group information to `vikunja_scope`: ```python -- 2.45.1 From 4771e7f05a38a0193a04f86623e49f6287deecc3 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 23 Feb 2024 14:21:40 +0100 Subject: [PATCH 85/93] changed assert to require in openid test --- magefile.go | 3 +- pkg/modules/auth/openid/openid_test.go | 46 +++++++++++++------------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/magefile.go b/magefile.go index f58040b6c..569257455 100644 --- a/magefile.go +++ b/magefile.go @@ -25,7 +25,6 @@ import ( "context" "crypto/sha256" "fmt" - "github.com/iancoleman/strcase" "io" "os" "os/exec" @@ -34,6 +33,8 @@ import ( "strings" "time" + "github.com/iancoleman/strcase" + "github.com/magefile/mage/mg" "golang.org/x/sync/errgroup" "gopkg.in/yaml.v3" diff --git a/pkg/modules/auth/openid/openid_test.go b/pkg/modules/auth/openid/openid_test.go index bff4d149f..ea9b6fa22 100644 --- a/pkg/modules/auth/openid/openid_test.go +++ b/pkg/modules/auth/openid/openid_test.go @@ -112,16 +112,16 @@ func TestGetOrCreateUser(t *testing.T) { } u, err := getOrCreateUser(s, cl, "https://some.service.com", "12345") - assert.NoError(t, err) + require.NoError(t, err) teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, nil) for _, err := range errs { - assert.NoError(t, err) + require.NoError(t, err) } - assert.NoError(t, err) + require.NoError(t, err) oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) - assert.NoError(t, err) + require.NoError(t, err) err = s.Commit() - assert.NoError(t, err) + require.NoError(t, err) db.AssertExists(t, "users", map[string]interface{}{ "id": u.ID, @@ -150,12 +150,12 @@ func TestGetOrCreateUser(t *testing.T) { u := &user.User{ID: 10} teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, nil) for _, err := range errs { - assert.NoError(t, err) + require.NoError(t, err) } oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) - assert.NoError(t, err) + require.NoError(t, err) err = s.Commit() - assert.NoError(t, err) + require.NoError(t, err) db.AssertExists(t, "team_members", map[string]interface{}{ "team_id": oidcTeams, @@ -176,27 +176,27 @@ func TestGetOrCreateUser(t *testing.T) { teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, nil) if len(errs) > 0 { for _, err := range errs { - assert.NoError(t, err) + require.NoError(t, err) } } oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) - assert.NoError(t, err) + require.NoError(t, err) oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) - assert.NoError(t, err) + require.NoError(t, err) teamIDsToLeave := utils.NotIn(oldOidcTeams, oidcTeams) - assert.NoError(t, err) + require.NoError(t, err) err = RemoveUserFromTeamsByIds(s, u, teamIDsToLeave) - assert.NoError(t, err) + require.NoError(t, err) errs = RemoveEmptySSOTeams(s, teamIDsToLeave) for _, err = range errs { - assert.NoError(t, err) + require.NoError(t, err) } errs = RemoveEmptySSOTeams(s, teamIDsToLeave) for _, err = range errs { - assert.NoError(t, err) + require.NoError(t, err) } err = s.Commit() - assert.NoError(t, err) + require.NoError(t, err) db.AssertMissing(t, "team_members", map[string]interface{}{ "team_id": oidcTeams, @@ -217,23 +217,23 @@ func TestGetOrCreateUser(t *testing.T) { teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, nil) if len(errs) > 0 { for _, err := range errs { - assert.NoError(t, err) + require.NoError(t, err) } } oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID) - assert.NoError(t, err) + require.NoError(t, err) oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData) - assert.NoError(t, err) + require.NoError(t, err) teamIDsToLeave := utils.NotIn(oldOidcTeams, oidcTeams) - assert.NoError(t, err) + require.NoError(t, err) err = RemoveUserFromTeamsByIds(s, u, teamIDsToLeave) - assert.NoError(t, err) + require.NoError(t, err) errs = RemoveEmptySSOTeams(s, teamIDsToLeave) for _, err := range errs { - assert.NoError(t, err) + require.NoError(t, err) } err = s.Commit() - assert.NoError(t, err) + require.NoError(t, err) db.AssertMissing(t, "teams", map[string]interface{}{ "id": oidcTeams, }) -- 2.45.1 From 914bcfabbcac4bd79974dc80f9ae783ae72740d1 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 23 Feb 2024 14:56:56 +0100 Subject: [PATCH 86/93] work on docs --- docs/content/doc/setup/openid.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/doc/setup/openid.md b/docs/content/doc/setup/openid.md index 7e257996f..21d9e58f4 100644 --- a/docs/content/doc/setup/openid.md +++ b/docs/content/doc/setup/openid.md @@ -14,9 +14,9 @@ Teams which exist only because they were created from oidc attributes are not ed To distinguish between teams created in Vikunja and teams generated automatically via oidc, generated teams have an `oidcID` assigned internally. -You need to make sure the OpenID provider has the `vikunja_groups` scope via your custom scope since this is the key, which is looked up by Vikunja to start the procedure. +You need to make sure the OpenID provider offers a `vikunja_groups` key through your custom scope. This is the key, which is looked up by Vikunja to start the procedure. -Additionally, make sure to deliver an `oidcID` and a `name` attribute in the oidc token. +Additionally, make sure to deliver an `oidcID` and a `name` attribute within the `vikunja_groups`. You can see how to set this up, if you continue reading. ### Setup in Authentik -- 2.45.1 From 75c3c0fc9115a6d6a53781777ea66f5cd785b971 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 1 Mar 2024 14:24:14 +0100 Subject: [PATCH 87/93] add frontend code from #3033 --- frontend/embed.go | 2 +- frontend/src/helpers/redirectToProvider.ts | 9 ++++++--- frontend/src/modelTypes/ITeam.ts | 1 + frontend/src/models/team.ts | 1 + frontend/src/types/IProvider.ts | 1 + frontend/src/views/teams/EditTeam.vue | 4 ++-- frontend/src/views/teams/ListTeams.vue | 10 ++++++---- 7 files changed, 18 insertions(+), 10 deletions(-) diff --git a/frontend/embed.go b/frontend/embed.go index 0be5b002d..1a2b830bd 100644 --- a/frontend/embed.go +++ b/frontend/embed.go @@ -18,5 +18,5 @@ package frontend import "embed" -//go:embed dist +// go:embed dist var Files embed.FS diff --git a/frontend/src/helpers/redirectToProvider.ts b/frontend/src/helpers/redirectToProvider.ts index 236394de8..00f063aa0 100644 --- a/frontend/src/helpers/redirectToProvider.ts +++ b/frontend/src/helpers/redirectToProvider.ts @@ -11,14 +11,17 @@ export function getRedirectUrlFromCurrentFrontendPath(provider: IProvider): stri export const redirectToProvider = (provider: IProvider) => { - console.log({provider}) - const redirectUrl = getRedirectUrlFromCurrentFrontendPath(provider) const state = createRandomID(24) localStorage.setItem('state', state) - window.location.href = `${provider.authUrl}?client_id=${provider.clientId}&redirect_uri=${redirectUrl}&response_type=code&scope=openid email profile&state=${state}` + let scope = 'openid email profile' + if (provider.scope !== null){ + scope = provider.scope + } + window.location.href = `${provider.authUrl}?client_id=${provider.clientId}&redirect_uri=${redirectUrl}&response_type=code&scope=${scope}&state=${state}` } + export const redirectToProviderOnLogout = (provider: IProvider) => { if (provider.logoutUrl.length > 0) { window.location.href = `${provider.logoutUrl}` diff --git a/frontend/src/modelTypes/ITeam.ts b/frontend/src/modelTypes/ITeam.ts index cd5a7dc73..3cdaae987 100644 --- a/frontend/src/modelTypes/ITeam.ts +++ b/frontend/src/modelTypes/ITeam.ts @@ -9,6 +9,7 @@ export interface ITeam extends IAbstract { description: string members: ITeamMember[] right: Right + oidcId: string createdBy: IUser created: Date diff --git a/frontend/src/models/team.ts b/frontend/src/models/team.ts index 9d86ca8c4..1e75738bb 100644 --- a/frontend/src/models/team.ts +++ b/frontend/src/models/team.ts @@ -13,6 +13,7 @@ export default class TeamModel extends AbstractModel implements ITeam { description = '' members: ITeamMember[] = [] right: Right = RIGHTS.READ + oidcId = '' createdBy: IUser = {} // FIXME: seems wrong created: Date = null diff --git a/frontend/src/types/IProvider.ts b/frontend/src/types/IProvider.ts index 420728926..2dec662a6 100644 --- a/frontend/src/types/IProvider.ts +++ b/frontend/src/types/IProvider.ts @@ -4,4 +4,5 @@ export interface IProvider { authUrl: string; clientId: string; logoutUrl: string; + scope: string; } diff --git a/frontend/src/views/teams/EditTeam.vue b/frontend/src/views/teams/EditTeam.vue index 03cc7e96c..5ee820175 100644 --- a/frontend/src/views/teams/EditTeam.vue +++ b/frontend/src/views/teams/EditTeam.vue @@ -4,7 +4,7 @@ :class="{ 'is-loading': teamService.loading }" > @@ -77,7 +77,7 @@ :padding="false" >
diff --git a/frontend/src/views/teams/ListTeams.vue b/frontend/src/views/teams/ListTeams.vue index a7f01c7d0..3f57133fa 100644 --- a/frontend/src/views/teams/ListTeams.vue +++ b/frontend/src/views/teams/ListTeams.vue @@ -17,11 +17,13 @@ class="teams box" >
  • - - {{ team.name }} + +

    + {{ t.name + (t.oidcId ? ` (sso: ${t.oidcId})`: '') }} +

  • -- 2.45.1 From efade3563d20937420951bdd8ba45163b695f320 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Fri, 1 Mar 2024 14:40:58 +0100 Subject: [PATCH 88/93] restore pnpm.lock from main --- frontend/embed.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/embed.go b/frontend/embed.go index 1a2b830bd..0be5b002d 100644 --- a/frontend/embed.go +++ b/frontend/embed.go @@ -18,5 +18,5 @@ package frontend import "embed" -// go:embed dist +//go:embed dist var Files embed.FS -- 2.45.1 From e95adab54c2bd9737e082cdd35d651dcb9132488 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 2 Mar 2024 09:21:00 +0100 Subject: [PATCH 89/93] chore: update pnpm lockfile --- frontend/pnpm-lock.yaml | 1994 +++++++++++++++++++-------------------- 1 file changed, 987 insertions(+), 1007 deletions(-) diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 967c879a7..f9e11e871 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -21,124 +21,124 @@ dependencies: version: 6.5.1 '@fortawesome/vue-fontawesome': specifier: 3.0.6 - version: 3.0.6(@fortawesome/fontawesome-svg-core@6.5.1)(vue@3.4.21) + version: 3.0.6(@fortawesome/fontawesome-svg-core@6.5.1)(vue@3.4.19) '@github/hotkey': specifier: 3.1.0 version: 3.1.0 '@infectoone/vue-ganttastic': specifier: 2.2.0 - version: 2.2.0(dayjs@1.11.10)(vue@3.4.21) + version: 2.2.0(dayjs@1.11.10)(vue@3.4.19) '@intlify/unplugin-vue-i18n': specifier: 2.0.0 - version: 2.0.0(rollup@4.12.0)(vue-i18n@9.9.1) + version: 2.0.0(rollup@4.9.6)(vue-i18n@9.9.1) '@kyvg/vue3-notification': specifier: 3.2.0 - version: 3.2.0(vue@3.4.21) + version: 3.2.0(vue@3.4.19) '@sentry/tracing': - specifier: 7.103.0 - version: 7.103.0 + specifier: 7.102.0 + version: 7.102.0 '@sentry/vue': - specifier: 7.103.0 - version: 7.103.0(vue@3.4.21) + specifier: 7.102.0 + version: 7.102.0(vue@3.4.19) '@tiptap/core': - specifier: 2.2.4 - version: 2.2.4(@tiptap/pm@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/pm@2.2.3) '@tiptap/extension-blockquote': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-bold': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-bullet-list': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-code': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-code-block-lowlight': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/extension-code-block@2.1.12)(@tiptap/pm@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/extension-code-block@2.1.12)(@tiptap/pm@2.2.3) '@tiptap/extension-document': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-dropcursor': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) '@tiptap/extension-gapcursor': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) '@tiptap/extension-hard-break': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-heading': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-history': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) '@tiptap/extension-horizontal-rule': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) '@tiptap/extension-image': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-italic': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-link': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) '@tiptap/extension-list-item': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-ordered-list': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-paragraph': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-placeholder': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) '@tiptap/extension-strike': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-table': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) '@tiptap/extension-table-cell': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-table-header': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-table-row': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-task-item': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) '@tiptap/extension-task-list': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-text': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-typography': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/extension-underline': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3) '@tiptap/pm': - specifier: 2.2.4 - version: 2.2.4 + specifier: 2.2.3 + version: 2.2.3 '@tiptap/suggestion': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) '@tiptap/vue-3': - specifier: 2.2.4 - version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4)(vue@3.4.21) + specifier: 2.2.3 + version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3)(vue@3.4.19) '@types/is-touch-device': specifier: 1.0.2 version: 1.0.2 @@ -146,11 +146,11 @@ dependencies: specifier: 4.5.9 version: 4.5.9 '@vueuse/core': - specifier: 10.9.0 - version: 10.9.0(vue@3.4.21) + specifier: 10.8.0 + version: 10.8.0(vue@3.4.19) '@vueuse/router': - specifier: 10.9.0 - version: 10.9.0(vue-router@4.3.0)(vue@3.4.21) + specifier: 10.8.0 + version: 10.8.0(vue-router@4.3.0)(vue@3.4.19) axios: specifier: 1.6.7 version: 1.6.7(debug@4.3.4) @@ -183,7 +183,7 @@ dependencies: version: 0.7.31(patch_hash=bfn3sngfuhktmdj7jgl3ejl35y) floating-vue: specifier: 5.2.2 - version: 5.2.2(vue@3.4.21) + version: 5.2.2(vue@3.4.19) is-touch-device: specifier: 1.0.1 version: 1.0.1 @@ -198,7 +198,7 @@ dependencies: version: 2.9.0 pinia: specifier: 2.1.7 - version: 2.1.7(typescript@5.3.3)(vue@3.4.21) + version: 2.1.7(typescript@5.3.3)(vue@3.4.19) register-service-worker: specifier: 1.7.2 version: 1.7.2 @@ -215,46 +215,46 @@ dependencies: specifier: 1.4.0 version: 1.4.0 vue: - specifier: 3.4.21 - version: 3.4.21(typescript@5.3.3) + specifier: 3.4.19 + version: 3.4.19(typescript@5.3.3) vue-advanced-cropper: specifier: 2.8.8 - version: 2.8.8(vue@3.4.21) + version: 2.8.8(vue@3.4.19) vue-flatpickr-component: specifier: 11.0.4 - version: 11.0.4(vue@3.4.21) + version: 11.0.4(vue@3.4.19) vue-i18n: specifier: 9.9.1 - version: 9.9.1(vue@3.4.21) + version: 9.9.1(vue@3.4.19) vue-router: specifier: 4.3.0 - version: 4.3.0(vue@3.4.21) + version: 4.3.0(vue@3.4.19) workbox-precaching: specifier: 7.0.0 version: 7.0.0 zhyswan-vuedraggable: specifier: 4.1.3 - version: 4.1.3(vue@3.4.21) + version: 4.1.3(vue@3.4.19) devDependencies: '@4tw/cypress-drag-drop': specifier: 2.2.5 - version: 2.2.5(cypress@13.6.6) + version: 2.2.5(cypress@13.6.3) '@cypress/vite-dev-server': specifier: 5.0.7 version: 5.0.7 '@cypress/vue': specifier: 6.0.0 - version: 6.0.0(cypress@13.6.6)(vue@3.4.21) + version: 6.0.0(cypress@13.6.3)(vue@3.4.19) '@faker-js/faker': - specifier: 8.4.1 - version: 8.4.1 + specifier: 8.4.0 + version: 8.4.0 '@histoire/plugin-screenshot': specifier: 0.17.8 version: 0.17.8(histoire@0.17.9) '@histoire/plugin-vue': - specifier: 0.17.12 - version: 0.17.12(histoire@0.17.9)(vite@5.1.4)(vue@3.4.21) + specifier: 0.17.9 + version: 0.17.9(histoire@0.17.9)(vite@5.0.12)(vue@3.4.19) '@rushstack/eslint-patch': specifier: 1.7.2 version: 1.7.2 @@ -277,92 +277,92 @@ devDependencies: specifier: 5.0.2 version: 5.0.2 '@types/node': - specifier: 20.11.22 - version: 20.11.22 + specifier: 20.11.10 + version: 20.11.10 '@types/postcss-preset-env': specifier: 7.7.0 version: 7.7.0 '@types/sortablejs': - specifier: 1.15.8 - version: 1.15.8 + specifier: 1.15.7 + version: 1.15.7 '@typescript-eslint/eslint-plugin': - specifier: 7.1.0 - version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3) + specifier: 7.0.1 + version: 7.0.1(@typescript-eslint/parser@7.0.1)(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/parser': - specifier: 7.1.0 - version: 7.1.0(eslint@8.57.0)(typescript@5.3.3) + specifier: 7.0.1 + version: 7.0.1(eslint@8.56.0)(typescript@5.3.3) '@vitejs/plugin-legacy': - specifier: 5.3.1 - version: 5.3.1(esbuild@0.20.1)(terser@5.24.0)(vite@5.1.4) + specifier: 5.3.0 + version: 5.3.0(esbuild@0.20.0)(terser@5.24.0)(vite@5.0.12) '@vitejs/plugin-vue': - specifier: 5.0.4 - version: 5.0.4(vite@5.1.4)(vue@3.4.21) + specifier: 5.0.3 + version: 5.0.3(vite@5.0.12)(vue@3.4.19) '@vue/eslint-config-typescript': specifier: 12.0.0 - version: 12.0.0(eslint-plugin-vue@9.22.0)(eslint@8.57.0)(typescript@5.3.3) + version: 12.0.0(eslint-plugin-vue@9.20.1)(eslint@8.56.0)(typescript@5.3.3) '@vue/test-utils': specifier: 2.4.4 - version: 2.4.4(vue@3.4.21) + version: 2.4.4(vue@3.4.19) '@vue/tsconfig': specifier: 0.5.1 version: 0.5.1 autoprefixer: specifier: 10.4.17 - version: 10.4.17(postcss@8.4.35) + version: 10.4.17(postcss@8.4.33) browserslist: - specifier: 4.23.0 - version: 4.23.0 + specifier: 4.22.3 + version: 4.22.3 caniuse-lite: - specifier: 1.0.30001591 - version: 1.0.30001591 + specifier: 1.0.30001581 + version: 1.0.30001581 css-has-pseudo: - specifier: 6.0.2 - version: 6.0.2(postcss@8.4.35) + specifier: 6.0.1 + version: 6.0.1(postcss@8.4.33) csstype: specifier: 3.1.3 version: 3.1.3 cypress: - specifier: 13.6.6 - version: 13.6.6 + specifier: 13.6.3 + version: 13.6.3 esbuild: - specifier: 0.20.1 - version: 0.20.1 + specifier: 0.20.0 + version: 0.20.0 eslint: - specifier: 8.57.0 - version: 8.57.0 + specifier: 8.56.0 + version: 8.56.0 eslint-plugin-vue: - specifier: 9.22.0 - version: 9.22.0(eslint@8.57.0) + specifier: 9.20.1 + version: 9.20.1(eslint@8.56.0) happy-dom: - specifier: 13.6.2 - version: 13.6.2 + specifier: 13.3.5 + version: 13.3.5 histoire: specifier: 0.17.9 - version: 0.17.9(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0)(vite@5.1.4) + version: 0.17.9(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0)(vite@5.0.12) postcss: - specifier: 8.4.35 - version: 8.4.35 + specifier: 8.4.33 + version: 8.4.33 postcss-easing-gradients: specifier: 3.0.1 version: 3.0.1 postcss-easings: specifier: 4.0.0 - version: 4.0.0(postcss@8.4.35) + version: 4.0.0(postcss@8.4.33) postcss-focus-within: specifier: 8.0.1 - version: 8.0.1(postcss@8.4.35) + version: 8.0.1(postcss@8.4.33) postcss-preset-env: - specifier: 9.4.0 - version: 9.4.0(postcss@8.4.35) + specifier: 9.3.0 + version: 9.3.0(postcss@8.4.33) rollup: - specifier: 4.12.0 - version: 4.12.0 + specifier: 4.9.6 + version: 4.9.6 rollup-plugin-visualizer: specifier: 5.12.0 - version: 5.12.0(rollup@4.12.0) + version: 5.12.0(rollup@4.9.6) sass: - specifier: 1.71.1 - version: 1.71.1 + specifier: 1.70.0 + version: 1.70.0 start-server-and-test: specifier: 2.0.3 version: 2.0.3 @@ -370,23 +370,23 @@ devDependencies: specifier: 5.3.3 version: 5.3.3 vite: - specifier: 5.1.4 - version: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + specifier: 5.0.12 + version: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) vite-plugin-inject-preload: specifier: 1.3.3 - version: 1.3.3(vite@5.1.4) + version: 1.3.3(vite@5.0.12) vite-plugin-pwa: - specifier: 0.19.1 - version: 0.19.1(vite@5.1.4)(workbox-build@7.0.0)(workbox-window@7.0.0) + specifier: 0.17.5 + version: 0.17.5(vite@5.0.12)(workbox-build@7.0.0)(workbox-window@7.0.0) vite-plugin-sentry: - specifier: 1.4.0 - version: 1.4.0(vite@5.1.4) + specifier: 1.3.0 + version: 1.3.0(vite@5.0.12) vite-svg-loader: specifier: 5.1.0 - version: 5.1.0(vue@3.4.21) + version: 5.1.0(vue@3.4.19) vitest: - specifier: 1.3.1 - version: 1.3.1(@types/node@20.11.22)(happy-dom@13.6.2)(sass@1.71.1)(terser@5.24.0) + specifier: 1.2.2 + version: 1.2.2(@types/node@20.11.10)(happy-dom@13.3.5)(sass@1.70.0)(terser@5.24.0) vue-tsc: specifier: 1.8.27 version: 1.8.27(typescript@5.3.3) @@ -399,12 +399,12 @@ devDependencies: packages: - /@4tw/cypress-drag-drop@2.2.5(cypress@13.6.6): + /@4tw/cypress-drag-drop@2.2.5(cypress@13.6.3): resolution: {integrity: sha512-3ghTmzhOmUqeN6U3QmUnKRUxI7OMLbJA4hHUY/eS/FhWJgxbiGgcaELbolWnBAOpajPXcsNQGYEj9brd59WH6A==} peerDependencies: cypress: 2 - 13 dependencies: - cypress: 13.6.6 + cypress: 13.6.3 dev: true /@aashutoshrathi/word-wrap@1.2.6: @@ -526,7 +526,7 @@ packages: dependencies: '@babel/compat-data': 7.23.5 '@babel/helper-validator-option': 7.23.5 - browserslist: 4.23.0 + browserslist: 4.22.3 lru-cache: 5.1.1 semver: 6.3.1 dev: true @@ -2719,18 +2719,18 @@ packages: '@csstools/css-tokenizer': 2.2.3 dev: true - /@csstools/postcss-cascade-layers@4.0.3(postcss@8.4.35): + /@csstools/postcss-cascade-layers@4.0.3(postcss@8.4.33): resolution: {integrity: sha512-RbkQoOH23yGhWVetgBTwFgIOHEyU2tKMN7blTz/YAKKabR6tr9pP7mYS23Q9snFY2hr8WSaV8Le64KdM9BtUSA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.13) - postcss: 8.4.35 - postcss-selector-parser: 6.0.13 + '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.15) + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 dev: true - /@csstools/postcss-color-function@3.0.10(postcss@8.4.35): + /@csstools/postcss-color-function@3.0.10(postcss@8.4.33): resolution: {integrity: sha512-jxiXmSl4ZYX8KewFjL5ef6of9uW73VkaHeDb2tqb5q4ZDPYxjusNX1KJ8UXY8+7ydqS5QBo42tVMrSMGy+rDmw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2739,12 +2739,12 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 dev: true - /@csstools/postcss-color-mix-function@2.0.10(postcss@8.4.35): + /@csstools/postcss-color-mix-function@2.0.10(postcss@8.4.33): resolution: {integrity: sha512-zeD856+FDCUjB077pPS+Z9OnTQnqpiJrao3TW+sasCb/gJ3vZCX7sRSRFsRUo0/MntTtJu9hkKv9eMkFmfjydA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2753,12 +2753,12 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 dev: true - /@csstools/postcss-exponential-functions@1.0.4(postcss@8.4.35): + /@csstools/postcss-exponential-functions@1.0.4(postcss@8.4.33): resolution: {integrity: sha512-frMf0CFVnZoGEKAHlxLy3s4g/tpjyFn5+A+h895UJNm9Uc+ewGT7+EeK7Kh9IHH4pD4FkaGW1vOQtER00PLurQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2767,21 +2767,21 @@ packages: '@csstools/css-calc': 1.1.7(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /@csstools/postcss-font-format-keywords@3.0.2(postcss@8.4.35): + /@csstools/postcss-font-format-keywords@3.0.2(postcss@8.4.33): resolution: {integrity: sha512-E0xz2sjm4AMCkXLCFvI/lyl4XO6aN1NCSMMVEOngFDJ+k2rDwfr6NDjWljk1li42jiLNChVX+YFnmfGCigZKXw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-gamut-mapping@1.0.3(postcss@8.4.35): + /@csstools/postcss-gamut-mapping@1.0.3(postcss@8.4.33): resolution: {integrity: sha512-P0+ude1KyCy9LXOe2pHJmpcXK4q/OQbr2Sn2wQSssMw0rALGmny2MfHiCqEu8n6mf2cN6lWDZdzY8enBk8WHXQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2790,10 +2790,10 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /@csstools/postcss-gradients-interpolation-method@4.0.11(postcss@8.4.35): + /@csstools/postcss-gradients-interpolation-method@4.0.11(postcss@8.4.33): resolution: {integrity: sha512-LFom5jCVUfzF+iuiOZvhvX7RRN8vc+tKpcKo9s4keEBAU2mPwV5/Fgz5iylEfXP/DZbEdq2C0At20urMi/lupw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2802,12 +2802,12 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 dev: true - /@csstools/postcss-hwb-function@3.0.9(postcss@8.4.35): + /@csstools/postcss-hwb-function@3.0.9(postcss@8.4.33): resolution: {integrity: sha512-S3/Z+mGHWIKAex7DLsHFDiku5lBEK34avT2My6sGPNCXB38TZjrKI0rd7JdN9oulem5sn+CU7oONyIftui24oQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2816,105 +2816,92 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 dev: true - /@csstools/postcss-ic-unit@3.0.4(postcss@8.4.35): + /@csstools/postcss-ic-unit@3.0.4(postcss@8.4.33): resolution: {integrity: sha512-OB6ojl33/TQHhjVx1NI+n3EnYbdUM6Q/mSUv3WFATdcz7IrH/CmBaZt7P1R6j1Xdp58thIa6jm4Je7saGs+2AA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-initial@1.0.1(postcss@8.4.35): + /@csstools/postcss-initial@1.0.1(postcss@8.4.33): resolution: {integrity: sha512-wtb+IbUIrIf8CrN6MLQuFR7nlU5C7PwuebfeEXfjthUha1+XZj2RVi+5k/lukToA24sZkYAiSJfHM8uG/UZIdg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /@csstools/postcss-is-pseudo-class@4.0.5(postcss@8.4.35): + /@csstools/postcss-is-pseudo-class@4.0.5(postcss@8.4.33): resolution: {integrity: sha512-qG3MI7IN3KY9UwdaE9E7G7sFydscVW7nAj5OGwaBP9tQPEEVdxXTGI+l1ZW5EUpZFSj+u3q/22fH5+8HI72+Bg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.13) - postcss: 8.4.35 - postcss-selector-parser: 6.0.13 + '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.15) + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 dev: true - /@csstools/postcss-light-dark-function@1.0.0(postcss@8.4.35): - resolution: {integrity: sha512-KHo633V16DGo6tmpr1ARAwO73CPBNmDI3PfSQYe7ZBMiv60WEizbcEroK75fHjxKYJ4tj9uCCzp5sYG4cEUqqw==} - engines: {node: ^14 || ^16 || >=18} - peerDependencies: - postcss: ^8.4 - dependencies: - '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) - '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 - dev: true - - /@csstools/postcss-logical-float-and-clear@2.0.1(postcss@8.4.35): + /@csstools/postcss-logical-float-and-clear@2.0.1(postcss@8.4.33): resolution: {integrity: sha512-SsrWUNaXKr+e/Uo4R/uIsqJYt3DaggIh/jyZdhy/q8fECoJSKsSMr7nObSLdvoULB69Zb6Bs+sefEIoMG/YfOA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /@csstools/postcss-logical-overflow@1.0.1(postcss@8.4.35): + /@csstools/postcss-logical-overflow@1.0.1(postcss@8.4.33): resolution: {integrity: sha512-Kl4lAbMg0iyztEzDhZuQw8Sj9r2uqFDcU1IPl+AAt2nue8K/f1i7ElvKtXkjhIAmKiy5h2EY8Gt/Cqg0pYFDCw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /@csstools/postcss-logical-overscroll-behavior@1.0.1(postcss@8.4.35): + /@csstools/postcss-logical-overscroll-behavior@1.0.1(postcss@8.4.33): resolution: {integrity: sha512-+kHamNxAnX8ojPCtV8WPcUP3XcqMFBSDuBuvT6MHgq7oX4IQxLIXKx64t7g9LiuJzE7vd06Q9qUYR6bh4YnGpQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /@csstools/postcss-logical-resize@2.0.1(postcss@8.4.35): + /@csstools/postcss-logical-resize@2.0.1(postcss@8.4.33): resolution: {integrity: sha512-W5Gtwz7oIuFcKa5SmBjQ2uxr8ZoL7M2bkoIf0T1WeNqljMkBrfw1DDA8/J83k57NQ1kcweJEjkJ04pUkmyee3A==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-logical-viewport-units@2.0.6(postcss@8.4.35): + /@csstools/postcss-logical-viewport-units@2.0.6(postcss@8.4.33): resolution: {integrity: sha512-6hV0ngZh8J7HqNY3kyt+z5ABN/XE18qvrU7ne4YSkKfltrWDnQgGiW/Q+h7bdQz8/W5juAefcdCCAJUIBE7erg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: '@csstools/css-tokenizer': 2.2.3 - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 dev: true - /@csstools/postcss-media-minmax@1.1.3(postcss@8.4.35): + /@csstools/postcss-media-minmax@1.1.3(postcss@8.4.33): resolution: {integrity: sha512-W9AFRQSLvT+Dxtp20AewzGTUxzkJ21XSKzqRALwQdAv0uJGXkR76qgdhkoX0L/tcV4gXtgDfVtGYL/x2Nz/M5Q==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2924,10 +2911,10 @@ packages: '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 '@csstools/media-query-list-parser': 2.1.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /@csstools/postcss-media-queries-aspect-ratio-number-values@2.0.6(postcss@8.4.35): + /@csstools/postcss-media-queries-aspect-ratio-number-values@2.0.6(postcss@8.4.33): resolution: {integrity: sha512-awc2qenSDvx6r+w6G9xxENp+LsbvHC8mMMV23KYmk4pR3YL8JxeKPDSiDhmqd93FQ9nNNDc/CaCQEcvP+GV4rw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2936,31 +2923,31 @@ packages: '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 '@csstools/media-query-list-parser': 2.1.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /@csstools/postcss-nested-calc@3.0.2(postcss@8.4.35): + /@csstools/postcss-nested-calc@3.0.2(postcss@8.4.33): resolution: {integrity: sha512-ySUmPyawiHSmBW/VI44+IObcKH0v88LqFe0d09Sb3w4B1qjkaROc6d5IA3ll9kjD46IIX/dbO5bwFN/swyoyZA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-normalize-display-values@3.0.2(postcss@8.4.35): + /@csstools/postcss-normalize-display-values@3.0.2(postcss@8.4.33): resolution: {integrity: sha512-fCapyyT/dUdyPtrelQSIV+d5HqtTgnNP/BEG9IuhgXHt93Wc4CfC1bQ55GzKAjWrZbgakMQ7MLfCXEf3rlZJOw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-oklab-function@3.0.10(postcss@8.4.35): + /@csstools/postcss-oklab-function@3.0.10(postcss@8.4.33): resolution: {integrity: sha512-s9trs1c+gUMtaTtwrrIpdVQkUbRuwi6bQ9rBHaqwt4kd3kEnEYfP85uLY1inFx6Rt8OM2XVg3PSYbfnFSAO51A==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2969,22 +2956,22 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 dev: true - /@csstools/postcss-progressive-custom-properties@3.1.0(postcss@8.4.35): + /@csstools/postcss-progressive-custom-properties@3.1.0(postcss@8.4.33): resolution: {integrity: sha512-Mfb1T1BHa6pktLI+poMEHI7Q+VYvAsdwJZPFsSkIB2ZUsawCiPxXLw06BKSVPITxFlaY/FEUzfpyOTfX9YCE2w==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-relative-color-syntax@2.0.10(postcss@8.4.35): + /@csstools/postcss-relative-color-syntax@2.0.10(postcss@8.4.33): resolution: {integrity: sha512-IkTIk9Eq2VegSN4lgsljGY8boyfX3l3Pw58e+R9oyPe/Ye7r3NwuiQ3w0nkXoQ+RC+d240V6n7eZme2mEPqQvg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2993,22 +2980,22 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 dev: true - /@csstools/postcss-scope-pseudo-class@3.0.1(postcss@8.4.35): + /@csstools/postcss-scope-pseudo-class@3.0.1(postcss@8.4.33): resolution: {integrity: sha512-3ZFonK2gfgqg29gUJ2w7xVw2wFJ1eNWVDONjbzGkm73gJHVCYK5fnCqlLr+N+KbEfv2XbWAO0AaOJCFB6Fer6A==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 - postcss-selector-parser: 6.0.13 + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 dev: true - /@csstools/postcss-stepped-value-functions@3.0.5(postcss@8.4.35): + /@csstools/postcss-stepped-value-functions@3.0.5(postcss@8.4.33): resolution: {integrity: sha512-B8K8RaTrYVZLxbNzVUvFO3SlCDJDaUTAO7KRth05fa7f01ufPvb6ztdBuxSoRwOtmNp8iROxPJHOemWo2kBBtA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -3017,21 +3004,21 @@ packages: '@csstools/css-calc': 1.1.7(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /@csstools/postcss-text-decoration-shorthand@3.0.4(postcss@8.4.35): + /@csstools/postcss-text-decoration-shorthand@3.0.4(postcss@8.4.33): resolution: {integrity: sha512-yUZmbnUemgQmja7SpOZeU45+P49wNEgQguRdyTktFkZsHf7Gof+ZIYfvF6Cm+LsU1PwSupy4yUeEKKjX5+k6cQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: '@csstools/color-helpers': 4.0.0 - postcss: 8.4.35 + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-trigonometric-functions@3.0.5(postcss@8.4.35): + /@csstools/postcss-trigonometric-functions@3.0.5(postcss@8.4.33): resolution: {integrity: sha512-RhBfQ0TsBudyPuoo8pXKdfQuUiQxMU/Sc5GyV57bWk93JbUHXq6b4CdPx+B/tHUeFKvocVJn/e2jbu96rh0d3Q==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -3040,34 +3027,34 @@ packages: '@csstools/css-calc': 1.1.7(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /@csstools/postcss-unset-value@3.0.1(postcss@8.4.35): + /@csstools/postcss-unset-value@3.0.1(postcss@8.4.33): resolution: {integrity: sha512-dbDnZ2ja2U8mbPP0Hvmt2RMEGBiF1H7oY6HYSpjteXJGihYwgxgTr6KRbbJ/V6c+4wd51M+9980qG4gKVn5ttg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /@csstools/selector-specificity@3.0.2(postcss-selector-parser@6.0.13): + /@csstools/selector-specificity@3.0.2(postcss-selector-parser@6.0.15): resolution: {integrity: sha512-RpHaZ1h9LE7aALeQXmXrJkRG84ZxIsctEN2biEUmFyKpzFM3zZ35eUMcIzZFsw/2olQE6v69+esEqU2f1MKycg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss-selector-parser: ^6.0.13 dependencies: - postcss-selector-parser: 6.0.13 + postcss-selector-parser: 6.0.15 dev: true - /@csstools/utilities@1.0.0(postcss@8.4.35): + /@csstools/utilities@1.0.0(postcss@8.4.33): resolution: {integrity: sha512-tAgvZQe/t2mlvpNosA4+CkMiZ2azISW5WPAcdSalZlEjQvUfghHxfQcrCiK/7/CrfAWVxyM88kGFYO82heIGDg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 dev: true /@cypress/request@3.0.1: @@ -3105,7 +3092,7 @@ packages: - supports-color dev: true - /@cypress/vue@6.0.0(cypress@13.6.6)(vue@3.4.21): + /@cypress/vue@6.0.0(cypress@13.6.3)(vue@3.4.19): resolution: {integrity: sha512-KMfRw8y/kXn/RJqaDdFnYnW7YLk47313UE3Yip+sLDjILJ2kA0WEiEa6MYKe58v8TNRtwcRpUH5xAYVNs1N6/A==} engines: {node: '>=8'} peerDependencies: @@ -3116,8 +3103,8 @@ packages: '@cypress/webpack-dev-server': optional: true dependencies: - cypress: 13.6.6 - vue: 3.4.21(typescript@5.3.3) + cypress: 13.6.3 + vue: 3.4.19(typescript@5.3.3) dev: true /@cypress/xvfb@1.2.4(supports-color@8.1.1): @@ -3138,8 +3125,8 @@ packages: dev: true optional: true - /@esbuild/aix-ppc64@0.20.1: - resolution: {integrity: sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA==} + /@esbuild/aix-ppc64@0.20.0: + resolution: {integrity: sha512-fGFDEctNh0CcSwsiRPxiaqX0P5rq+AqE0SRhYGZ4PX46Lg1FNR6oCxJghf8YgY0WQEgQuh3lErUFE4KxLeRmmw==} engines: {node: '>=12'} cpu: [ppc64] os: [aix] @@ -3156,8 +3143,8 @@ packages: dev: true optional: true - /@esbuild/android-arm64@0.20.1: - resolution: {integrity: sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A==} + /@esbuild/android-arm64@0.20.0: + resolution: {integrity: sha512-aVpnM4lURNkp0D3qPoAzSG92VXStYmoVPOgXveAUoQBWRSuQzt51yvSju29J6AHPmwY1BjH49uR29oyfH1ra8Q==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -3174,8 +3161,8 @@ packages: dev: true optional: true - /@esbuild/android-arm@0.20.1: - resolution: {integrity: sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw==} + /@esbuild/android-arm@0.20.0: + resolution: {integrity: sha512-3bMAfInvByLHfJwYPJRlpTeaQA75n8C/QKpEaiS4HrFWFiJlNI0vzq/zCjBrhAYcPyVPG7Eo9dMrcQXuqmNk5g==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -3192,8 +3179,8 @@ packages: dev: true optional: true - /@esbuild/android-x64@0.20.1: - resolution: {integrity: sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA==} + /@esbuild/android-x64@0.20.0: + resolution: {integrity: sha512-uK7wAnlRvjkCPzh8jJ+QejFyrP8ObKuR5cBIsQZ+qbMunwR8sbd8krmMbxTLSrDhiPZaJYKQAU5Y3iMDcZPhyQ==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -3210,8 +3197,8 @@ packages: dev: true optional: true - /@esbuild/darwin-arm64@0.20.1: - resolution: {integrity: sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==} + /@esbuild/darwin-arm64@0.20.0: + resolution: {integrity: sha512-AjEcivGAlPs3UAcJedMa9qYg9eSfU6FnGHJjT8s346HSKkrcWlYezGE8VaO2xKfvvlZkgAhyvl06OJOxiMgOYQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -3228,8 +3215,8 @@ packages: dev: true optional: true - /@esbuild/darwin-x64@0.20.1: - resolution: {integrity: sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA==} + /@esbuild/darwin-x64@0.20.0: + resolution: {integrity: sha512-bsgTPoyYDnPv8ER0HqnJggXK6RyFy4PH4rtsId0V7Efa90u2+EifxytE9pZnsDgExgkARy24WUQGv9irVbTvIw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -3246,8 +3233,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64@0.20.1: - resolution: {integrity: sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw==} + /@esbuild/freebsd-arm64@0.20.0: + resolution: {integrity: sha512-kQ7jYdlKS335mpGbMW5tEe3IrQFIok9r84EM3PXB8qBFJPSc6dpWfrtsC/y1pyrz82xfUIn5ZrnSHQQsd6jebQ==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -3264,8 +3251,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-x64@0.20.1: - resolution: {integrity: sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg==} + /@esbuild/freebsd-x64@0.20.0: + resolution: {integrity: sha512-uG8B0WSepMRsBNVXAQcHf9+Ko/Tr+XqmK7Ptel9HVmnykupXdS4J7ovSQUIi0tQGIndhbqWLaIL/qO/cWhXKyQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -3282,8 +3269,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm64@0.20.1: - resolution: {integrity: sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w==} + /@esbuild/linux-arm64@0.20.0: + resolution: {integrity: sha512-uTtyYAP5veqi2z9b6Gr0NUoNv9F/rOzI8tOD5jKcCvRUn7T60Bb+42NDBCWNhMjkQzI0qqwXkQGo1SY41G52nw==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -3300,8 +3287,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm@0.20.1: - resolution: {integrity: sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw==} + /@esbuild/linux-arm@0.20.0: + resolution: {integrity: sha512-2ezuhdiZw8vuHf1HKSf4TIk80naTbP9At7sOqZmdVwvvMyuoDiZB49YZKLsLOfKIr77+I40dWpHVeY5JHpIEIg==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -3318,8 +3305,8 @@ packages: dev: true optional: true - /@esbuild/linux-ia32@0.20.1: - resolution: {integrity: sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw==} + /@esbuild/linux-ia32@0.20.0: + resolution: {integrity: sha512-c88wwtfs8tTffPaoJ+SQn3y+lKtgTzyjkD8NgsyCtCmtoIC8RDL7PrJU05an/e9VuAke6eJqGkoMhJK1RY6z4w==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -3336,8 +3323,8 @@ packages: dev: true optional: true - /@esbuild/linux-loong64@0.20.1: - resolution: {integrity: sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA==} + /@esbuild/linux-loong64@0.20.0: + resolution: {integrity: sha512-lR2rr/128/6svngnVta6JN4gxSXle/yZEZL3o4XZ6esOqhyR4wsKyfu6qXAL04S4S5CgGfG+GYZnjFd4YiG3Aw==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -3354,8 +3341,8 @@ packages: dev: true optional: true - /@esbuild/linux-mips64el@0.20.1: - resolution: {integrity: sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA==} + /@esbuild/linux-mips64el@0.20.0: + resolution: {integrity: sha512-9Sycc+1uUsDnJCelDf6ZNqgZQoK1mJvFtqf2MUz4ujTxGhvCWw+4chYfDLPepMEvVL9PDwn6HrXad5yOrNzIsQ==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -3372,8 +3359,8 @@ packages: dev: true optional: true - /@esbuild/linux-ppc64@0.20.1: - resolution: {integrity: sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw==} + /@esbuild/linux-ppc64@0.20.0: + resolution: {integrity: sha512-CoWSaaAXOZd+CjbUTdXIJE/t7Oz+4g90A3VBCHLbfuc5yUQU/nFDLOzQsN0cdxgXd97lYW/psIIBdjzQIwTBGw==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -3390,8 +3377,8 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64@0.20.1: - resolution: {integrity: sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg==} + /@esbuild/linux-riscv64@0.20.0: + resolution: {integrity: sha512-mlb1hg/eYRJUpv8h/x+4ShgoNLL8wgZ64SUr26KwglTYnwAWjkhR2GpoKftDbPOCnodA9t4Y/b68H4J9XmmPzA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -3408,8 +3395,8 @@ packages: dev: true optional: true - /@esbuild/linux-s390x@0.20.1: - resolution: {integrity: sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ==} + /@esbuild/linux-s390x@0.20.0: + resolution: {integrity: sha512-fgf9ubb53xSnOBqyvWEY6ukBNRl1mVX1srPNu06B6mNsNK20JfH6xV6jECzrQ69/VMiTLvHMicQR/PgTOgqJUQ==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -3426,8 +3413,8 @@ packages: dev: true optional: true - /@esbuild/linux-x64@0.20.1: - resolution: {integrity: sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA==} + /@esbuild/linux-x64@0.20.0: + resolution: {integrity: sha512-H9Eu6MGse++204XZcYsse1yFHmRXEWgadk2N58O/xd50P9EvFMLJTQLg+lB4E1cF2xhLZU5luSWtGTb0l9UeSg==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -3444,8 +3431,8 @@ packages: dev: true optional: true - /@esbuild/netbsd-x64@0.20.1: - resolution: {integrity: sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg==} + /@esbuild/netbsd-x64@0.20.0: + resolution: {integrity: sha512-lCT675rTN1v8Fo+RGrE5KjSnfY0x9Og4RN7t7lVrN3vMSjy34/+3na0q7RIfWDAj0e0rCh0OL+P88lu3Rt21MQ==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -3462,8 +3449,8 @@ packages: dev: true optional: true - /@esbuild/openbsd-x64@0.20.1: - resolution: {integrity: sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw==} + /@esbuild/openbsd-x64@0.20.0: + resolution: {integrity: sha512-HKoUGXz/TOVXKQ+67NhxyHv+aDSZf44QpWLa3I1lLvAwGq8x1k0T+e2HHSRvxWhfJrFxaaqre1+YyzQ99KixoA==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -3480,8 +3467,8 @@ packages: dev: true optional: true - /@esbuild/sunos-x64@0.20.1: - resolution: {integrity: sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q==} + /@esbuild/sunos-x64@0.20.0: + resolution: {integrity: sha512-GDwAqgHQm1mVoPppGsoq4WJwT3vhnz/2N62CzhvApFD1eJyTroob30FPpOZabN+FgCjhG+AgcZyOPIkR8dfD7g==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -3498,8 +3485,8 @@ packages: dev: true optional: true - /@esbuild/win32-arm64@0.20.1: - resolution: {integrity: sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A==} + /@esbuild/win32-arm64@0.20.0: + resolution: {integrity: sha512-0vYsP8aC4TvMlOQYozoksiaxjlvUcQrac+muDqj1Fxy6jh9l9CZJzj7zmh8JGfiV49cYLTorFLxg7593pGldwQ==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -3516,8 +3503,8 @@ packages: dev: true optional: true - /@esbuild/win32-ia32@0.20.1: - resolution: {integrity: sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw==} + /@esbuild/win32-ia32@0.20.0: + resolution: {integrity: sha512-p98u4rIgfh4gdpV00IqknBD5pC84LCub+4a3MO+zjqvU5MVXOc3hqR2UgT2jI2nh3h8s9EQxmOsVI3tyzv1iFg==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -3534,8 +3521,8 @@ packages: dev: true optional: true - /@esbuild/win32-x64@0.20.1: - resolution: {integrity: sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA==} + /@esbuild/win32-x64@0.20.0: + resolution: {integrity: sha512-NgJnesu1RtWihtTtXGFMU5YSE6JyyHPMxCwBZK7a6/8d31GuSo9l0Ss7w1Jw5QnKUawG6UEehs883kcXf5fYwg==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -3543,13 +3530,13 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.57.0 + eslint: 8.56.0 eslint-visitor-keys: 3.4.3 dev: true @@ -3575,13 +3562,13 @@ packages: - supports-color dev: true - /@eslint/js@8.57.0: - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + /@eslint/js@8.56.0: + resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@faker-js/faker@8.4.1: - resolution: {integrity: sha512-XQ3cU+Q8Uqmrbf2e0cIC/QN43sTBSC8KF12u29Mb47tWrt2hAgBXSgpZMj4Ao8Uk0iJcU99QsOCaIL8934obCg==} + /@faker-js/faker@8.4.0: + resolution: {integrity: sha512-htW87352wzUCdX1jyUQocUcmAaFqcR/w082EC8iP/gtkF0K+aKcBp0hR5Arb7dzR8tQ1TrhE9DNa5EbJELm84w==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13'} dev: true @@ -3625,14 +3612,14 @@ packages: '@fortawesome/fontawesome-common-types': 6.5.1 dev: false - /@fortawesome/vue-fontawesome@3.0.6(@fortawesome/fontawesome-svg-core@6.5.1)(vue@3.4.21): + /@fortawesome/vue-fontawesome@3.0.6(@fortawesome/fontawesome-svg-core@6.5.1)(vue@3.4.19): resolution: {integrity: sha512-akrL7lTroyNpPkoHtvK2UpsMzJr6jXdHaQ0YdcwqDsB8jdwlpNHZYijpOUd9KJsARr+VB3WXY4EyObepqJ4ytQ==} peerDependencies: '@fortawesome/fontawesome-svg-core': ~1 || ~6 vue: '>= 3.0.0 < 4' dependencies: '@fortawesome/fontawesome-svg-core': 6.5.1 - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) dev: false /@github/hotkey@3.1.0: @@ -3649,11 +3636,11 @@ packages: '@hapi/hoek': 9.2.1 dev: true - /@histoire/app@0.17.9(vite@5.1.4): + /@histoire/app@0.17.9(vite@5.0.12): resolution: {integrity: sha512-JoSGbsoo1/JY5TtTiMBUSPllIEJLvC6jHIGruvwPG/cJ3niqa3EyEMOsOWtcu+xjtx1uETgL9Yj5RJMJjC+OBA==} dependencies: - '@histoire/controls': 0.17.9(vite@5.1.4) - '@histoire/shared': 0.17.9(vite@5.1.4) + '@histoire/controls': 0.17.9(vite@5.0.12) + '@histoire/shared': 0.17.9(vite@5.0.12) '@histoire/vendors': 0.17.8 '@types/flexsearch': 0.7.6 flexsearch: 0.7.21 @@ -3662,7 +3649,7 @@ packages: - vite dev: true - /@histoire/controls@0.17.9(vite@5.1.4): + /@histoire/controls@0.17.9(vite@5.0.12): resolution: {integrity: sha512-1f1cE1NZ2emzGMRnGfAb/gCKDtBT3bUZzj3aAcDmhm3MA2Vy5tGYSb9j+KuTTj7+exhOrKefmedr9a0q1/5g2w==} dependencies: '@codemirror/commands': 6.3.2 @@ -3672,7 +3659,7 @@ packages: '@codemirror/state': 6.3.2 '@codemirror/theme-one-dark': 6.1.2 '@codemirror/view': 6.22.1 - '@histoire/shared': 0.17.9(vite@5.1.4) + '@histoire/shared': 0.17.9(vite@5.0.12) '@histoire/vendors': 0.17.8 transitivePeerDependencies: - vite @@ -3686,7 +3673,7 @@ packages: capture-website: 2.4.1 defu: 6.1.3 fs-extra: 10.1.0 - histoire: 0.17.9(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0)(vite@5.1.4) + histoire: 0.17.9(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0)(vite@5.0.12) pathe: 1.1.1 transitivePeerDependencies: - bufferutil @@ -3695,26 +3682,26 @@ packages: - utf-8-validate dev: true - /@histoire/plugin-vue@0.17.12(histoire@0.17.9)(vite@5.1.4)(vue@3.4.21): - resolution: {integrity: sha512-mpx2uwHq/qemnX+ARQtDR3M9kIt1y4kBCmzBkOquhJTp61mtHMu4hZKSzzQpQWA2QxEyuuwpaNiU7Mlms13EaQ==} + /@histoire/plugin-vue@0.17.9(histoire@0.17.9)(vite@5.0.12)(vue@3.4.19): + resolution: {integrity: sha512-iN/DEx7CSmYg9ho35zYB5laXuQ5kgBjG/5FH6hskI24hBhWzrUbPU9fynXBpBHwlAxX6r1mn2ngOVN1OW79CBw==} peerDependencies: histoire: ^0.17.9 vue: ^3.2.47 dependencies: - '@histoire/controls': 0.17.9(vite@5.1.4) - '@histoire/shared': 0.17.10(vite@5.1.4) + '@histoire/controls': 0.17.9(vite@5.0.12) + '@histoire/shared': 0.17.10(vite@5.0.12) '@histoire/vendors': 0.17.8 change-case: 4.1.2 globby: 13.2.2 - histoire: 0.17.9(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0)(vite@5.1.4) + histoire: 0.17.9(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0)(vite@5.0.12) launch-editor: 2.6.1 pathe: 1.1.1 - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) transitivePeerDependencies: - vite dev: true - /@histoire/shared@0.17.10(vite@5.1.4): + /@histoire/shared@0.17.10(vite@5.0.12): resolution: {integrity: sha512-8hzk/WKASrYfaJ+UtR6Mv7aZlP8IZvQ5POoHAi+JvHMJTtzCXZeuL0qdQAXg0zdk3vWIH20oSl6N8hZE1AP7yA==} peerDependencies: vite: ^2.9.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 @@ -3725,10 +3712,10 @@ packages: chokidar: 3.5.3 pathe: 1.1.1 picocolors: 1.0.0 - vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) dev: true - /@histoire/shared@0.17.9(vite@5.1.4): + /@histoire/shared@0.17.9(vite@5.0.12): resolution: {integrity: sha512-E/l4EzYc69/bOImUnvfi7h4/DHGl1rc96lkuMYulL5hjRjuNhSy5AlN5bG0nkVOG4RVIAnLGevMaMi207wtvLw==} peerDependencies: vite: ^2.9.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 @@ -3739,7 +3726,7 @@ packages: chokidar: 3.5.3 pathe: 1.1.1 picocolors: 1.0.0 - vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) dev: true /@histoire/vendors@0.17.8: @@ -3766,15 +3753,15 @@ packages: resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} dev: true - /@infectoone/vue-ganttastic@2.2.0(dayjs@1.11.10)(vue@3.4.21): + /@infectoone/vue-ganttastic@2.2.0(dayjs@1.11.10)(vue@3.4.19): resolution: {integrity: sha512-XvYGHP8FOPBavNR/ujuIAP2BYU2yrL+l9Xjn10VQeZfwdAvmh7aKXoAu+ONsnE2mBCA6h9r0AsLjfv/LYtW/tQ==} peerDependencies: dayjs: ^1.11.5 vue: ^3.2.40 dependencies: - '@vueuse/core': 9.13.0(vue@3.4.21) + '@vueuse/core': 9.13.0(vue@3.4.19) dayjs: 1.11.10 - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) transitivePeerDependencies: - '@vue/composition-api' dev: false @@ -3800,7 +3787,7 @@ packages: magic-string: 0.30.7 mlly: 1.4.2 source-map-js: 1.0.2 - vue-i18n: 9.9.1(vue@3.4.21) + vue-i18n: 9.9.1(vue@3.4.19) yaml-eslint-parser: 1.2.2 dev: false @@ -3843,7 +3830,7 @@ packages: engines: {node: '>= 16'} dev: false - /@intlify/unplugin-vue-i18n@2.0.0(rollup@4.12.0)(vue-i18n@9.9.1): + /@intlify/unplugin-vue-i18n@2.0.0(rollup@4.9.6)(vue-i18n@9.9.1): resolution: {integrity: sha512-1oKvm92L9l2od2H9wKx2ZvR4tzn7gUtd7bPLI7AWUmm7U9H1iEypndt5d985ypxGsEs0gToDaKTrytbBIJwwSg==} engines: {node: '>= 14.16'} peerDependencies: @@ -3860,7 +3847,7 @@ packages: dependencies: '@intlify/bundle-utils': 7.4.0(vue-i18n@9.9.1) '@intlify/shared': 9.8.0 - '@rollup/pluginutils': 5.0.2(rollup@4.12.0) + '@rollup/pluginutils': 5.0.2(rollup@4.9.6) '@vue/compiler-sfc': 3.3.13 debug: 4.3.4(supports-color@8.1.1) fast-glob: 3.3.2 @@ -3870,7 +3857,7 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 unplugin: 1.1.0 - vue-i18n: 9.9.1(vue@3.4.21) + vue-i18n: 9.9.1(vue@3.4.19) transitivePeerDependencies: - rollup - supports-color @@ -3927,12 +3914,12 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /@kyvg/vue3-notification@3.2.0(vue@3.4.21): + /@kyvg/vue3-notification@3.2.0(vue@3.4.19): resolution: {integrity: sha512-DKicfzxS6n7oMCkFoUqzb26Orjv8Oo3fhOgSDYM2I1mGDwBW+Tyb/yr2eauho0R+E5chNswZ3AUyAE9DqutXmg==} peerDependencies: vue: ^3.0.0 dependencies: - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) dev: false /@lezer/common@1.1.1: @@ -4099,7 +4086,7 @@ packages: rollup: 2.79.1 dev: true - /@rollup/pluginutils@5.0.2(rollup@4.12.0): + /@rollup/pluginutils@5.0.2(rollup@4.9.6): resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -4111,95 +4098,95 @@ packages: '@types/estree': 1.0.0 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 4.12.0 + rollup: 4.9.6 dev: false - /@rollup/rollup-android-arm-eabi@4.12.0: - resolution: {integrity: sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==} + /@rollup/rollup-android-arm-eabi@4.9.6: + resolution: {integrity: sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==} cpu: [arm] os: [android] requiresBuild: true optional: true - /@rollup/rollup-android-arm64@4.12.0: - resolution: {integrity: sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==} + /@rollup/rollup-android-arm64@4.9.6: + resolution: {integrity: sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==} cpu: [arm64] os: [android] requiresBuild: true optional: true - /@rollup/rollup-darwin-arm64@4.12.0: - resolution: {integrity: sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==} + /@rollup/rollup-darwin-arm64@4.9.6: + resolution: {integrity: sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==} cpu: [arm64] os: [darwin] requiresBuild: true optional: true - /@rollup/rollup-darwin-x64@4.12.0: - resolution: {integrity: sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==} + /@rollup/rollup-darwin-x64@4.9.6: + resolution: {integrity: sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==} cpu: [x64] os: [darwin] requiresBuild: true optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.12.0: - resolution: {integrity: sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==} + /@rollup/rollup-linux-arm-gnueabihf@4.9.6: + resolution: {integrity: sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==} cpu: [arm] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-arm64-gnu@4.12.0: - resolution: {integrity: sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==} + /@rollup/rollup-linux-arm64-gnu@4.9.6: + resolution: {integrity: sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-arm64-musl@4.12.0: - resolution: {integrity: sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==} + /@rollup/rollup-linux-arm64-musl@4.9.6: + resolution: {integrity: sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-riscv64-gnu@4.12.0: - resolution: {integrity: sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==} + /@rollup/rollup-linux-riscv64-gnu@4.9.6: + resolution: {integrity: sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==} cpu: [riscv64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-x64-gnu@4.12.0: - resolution: {integrity: sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==} + /@rollup/rollup-linux-x64-gnu@4.9.6: + resolution: {integrity: sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-x64-musl@4.12.0: - resolution: {integrity: sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==} + /@rollup/rollup-linux-x64-musl@4.9.6: + resolution: {integrity: sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-win32-arm64-msvc@4.12.0: - resolution: {integrity: sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==} + /@rollup/rollup-win32-arm64-msvc@4.9.6: + resolution: {integrity: sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==} cpu: [arm64] os: [win32] requiresBuild: true optional: true - /@rollup/rollup-win32-ia32-msvc@4.12.0: - resolution: {integrity: sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==} + /@rollup/rollup-win32-ia32-msvc@4.9.6: + resolution: {integrity: sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==} cpu: [ia32] os: [win32] requiresBuild: true optional: true - /@rollup/rollup-win32-x64-msvc@4.12.0: - resolution: {integrity: sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==} + /@rollup/rollup-win32-x64-msvc@4.9.6: + resolution: {integrity: sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==} cpu: [x64] os: [win32] requiresBuild: true @@ -4209,45 +4196,45 @@ packages: resolution: {integrity: sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==} dev: true - /@sentry-internal/feedback@7.103.0: - resolution: {integrity: sha512-2nYoCfP7FpiUR+xxO5y5BL2ajHrhM4fL7HSup6QKNn7gI7vLyllYOOuYFNHhSmsXCD0i00U8DBClGLcn+6DQqw==} + /@sentry-internal/feedback@7.102.0: + resolution: {integrity: sha512-GxHdzbOF4tg6TtyQzFqb/8c/p07n68qZC5KYwzs7AuW5ey0IPmdC58pOh3Kk52JA0P69/RZy39+r1p1Swr6C+Q==} engines: {node: '>=12'} dependencies: - '@sentry/core': 7.103.0 - '@sentry/types': 7.103.0 - '@sentry/utils': 7.103.0 + '@sentry/core': 7.102.0 + '@sentry/types': 7.102.0 + '@sentry/utils': 7.102.0 dev: false - /@sentry-internal/replay-canvas@7.103.0: - resolution: {integrity: sha512-EyDRMdlSqtwY8zGFhOWwl+nwwo98hlhJz+bpF5PQ6VmFpbplh6Wqfx2p+cPXQr40TGMMC4+vPFlSWTOMjcO9zQ==} + /@sentry-internal/replay-canvas@7.102.0: + resolution: {integrity: sha512-rgNO4PdFv0AYflBsCNbSIwpQuOOJQTqyu8i8U0PupjveNjkm0CUJhber/ZOcaGmbyjdvwikGwgWY2O0Oj0USCA==} engines: {node: '>=12'} dependencies: - '@sentry/core': 7.103.0 - '@sentry/replay': 7.103.0 - '@sentry/types': 7.103.0 - '@sentry/utils': 7.103.0 + '@sentry/core': 7.102.0 + '@sentry/replay': 7.102.0 + '@sentry/types': 7.102.0 + '@sentry/utils': 7.102.0 dev: false - /@sentry-internal/tracing@7.103.0: - resolution: {integrity: sha512-sZ/Wao8HOvGaBs7WlOdflMpHGAFkOBWL6hBiirHaOy5d+IDm7n7et5U6zhvcfiyYBO4nY36gy1Tg5mw+aNO0Vw==} + /@sentry-internal/tracing@7.102.0: + resolution: {integrity: sha512-BlE33HWL1IzkGa0W+pwTiyu01MUIfYf+WnO9UC8qkDW3jxVvg2zhoSjXSxikT+KPCOgoZpQHspaTzwjnI1LCvw==} engines: {node: '>=8'} dependencies: - '@sentry/core': 7.103.0 - '@sentry/types': 7.103.0 - '@sentry/utils': 7.103.0 + '@sentry/core': 7.102.0 + '@sentry/types': 7.102.0 + '@sentry/utils': 7.102.0 dev: false - /@sentry/browser@7.103.0: - resolution: {integrity: sha512-lP3Oplnwo1lY8ltk8SWzQURbxnSfVhYA099mVs1T95sdwXS16Za6SX7Ld/9T506ZW/WyoU4VCq7eKtG2kPFhMQ==} + /@sentry/browser@7.102.0: + resolution: {integrity: sha512-hIggcMnojIbWhbmlRfkykHmy6n7pjug0AHfF19HRUQxAx9KJfMH5YdWvohov0Hb9fS+jdvqgE+/4AWbEeXQrHw==} engines: {node: '>=8'} dependencies: - '@sentry-internal/feedback': 7.103.0 - '@sentry-internal/replay-canvas': 7.103.0 - '@sentry-internal/tracing': 7.103.0 - '@sentry/core': 7.103.0 - '@sentry/replay': 7.103.0 - '@sentry/types': 7.103.0 - '@sentry/utils': 7.103.0 + '@sentry-internal/feedback': 7.102.0 + '@sentry-internal/replay-canvas': 7.102.0 + '@sentry-internal/tracing': 7.102.0 + '@sentry/core': 7.102.0 + '@sentry/replay': 7.102.0 + '@sentry/types': 7.102.0 + '@sentry/utils': 7.102.0 dev: false /@sentry/cli@2.19.1: @@ -4266,54 +4253,54 @@ packages: - supports-color dev: true - /@sentry/core@7.103.0: - resolution: {integrity: sha512-LCI+PIDoF/RLqN41fNXum3ilmS6ukni6L7t38vSdibbe2G0804EbPLtOIpv2PkS8E6CFuRW5zOb+8OwEAAtZWw==} + /@sentry/core@7.102.0: + resolution: {integrity: sha512-GO9eLOSBK1waW4AD0wDXAreaNqXFQ1MPQZrkKcN+GJYEFhJK1+u+MSV7vO5Fs/rIfaTZIZ2jtEkxSSAOucE8EQ==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.103.0 - '@sentry/utils': 7.103.0 + '@sentry/types': 7.102.0 + '@sentry/utils': 7.102.0 dev: false - /@sentry/replay@7.103.0: - resolution: {integrity: sha512-I37komyb+DruQG8lPPPOFxLLbOijNXeTxiWLsIn+KFZqRtKqxxQWdNnk56V4YSTpFzxnMEFMRCpXhncuTWu4LA==} + /@sentry/replay@7.102.0: + resolution: {integrity: sha512-sUIBN4ZY0J5/dQS3KOe5VLykm856KZkTrhV8kmBEylzQhw1BBc8i2ehTILy5ZYh9Ra8uXPTAmtwpvYf/dRDfAg==} engines: {node: '>=12'} dependencies: - '@sentry-internal/tracing': 7.103.0 - '@sentry/core': 7.103.0 - '@sentry/types': 7.103.0 - '@sentry/utils': 7.103.0 + '@sentry-internal/tracing': 7.102.0 + '@sentry/core': 7.102.0 + '@sentry/types': 7.102.0 + '@sentry/utils': 7.102.0 dev: false - /@sentry/tracing@7.103.0: - resolution: {integrity: sha512-wlL9XidxcjC1dWXj7KSdYMgPgK+ry4dYy+YoW9gqRL+FbS6BJebV73Tni+5zponzCW+LMWP/IgMIB9IZt0WWTQ==} + /@sentry/tracing@7.102.0: + resolution: {integrity: sha512-2ZLgJw43qY7FjRHnnPGp4rOlPpsrcDGcFlnPIVJgfV14b4bfin1kMMeVgHc9O1S+DTfrkakcPnPnOg1qK1qltg==} engines: {node: '>=8'} dependencies: - '@sentry-internal/tracing': 7.103.0 + '@sentry-internal/tracing': 7.102.0 dev: false - /@sentry/types@7.103.0: - resolution: {integrity: sha512-NCvKyx8d2AGBQKPARrJemZmZ16DiMo688OEikZg4BbvFNDUzK5Egm2BH0vfLDhbNkU19o3maJowrYo42m8r9Zw==} + /@sentry/types@7.102.0: + resolution: {integrity: sha512-FPfFBP0x3LkPARw1/6cWySLq1djIo8ao3Qo2KNBeE9CHdq8bsS1a8zzjJLuWG4Ww+wieLP8/lY3WTgrCz4jowg==} engines: {node: '>=8'} dev: false - /@sentry/utils@7.103.0: - resolution: {integrity: sha512-phkUJt3F0UOkVq+M4GfdAh2ewI3ASrNiJddx9aO7GnT0aDwwVBHZltnqt95qgAB8W+BipTSt1dAh8yUbbq1Ceg==} + /@sentry/utils@7.102.0: + resolution: {integrity: sha512-cp5KCRe0slOVMwG4iP2Z4UajQkjryRTiFskZ5H7Q3X9R5voM8+DAhiDcIW88GL9NxqyUrAJOjmKdeLK2vM+bdA==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.103.0 + '@sentry/types': 7.102.0 dev: false - /@sentry/vue@7.103.0(vue@3.4.21): - resolution: {integrity: sha512-o5DlC+B6Yq39KY8SguyX2LWM+daPmjzv5teIx+Vj/MOXRb84gooEqgGvHTO/dlR7qhP89aSw7GRdnjyV+WO5WQ==} + /@sentry/vue@7.102.0(vue@3.4.19): + resolution: {integrity: sha512-wH/7/cuhy37W0E6is6nDvfasy3vmNTY1w4AUpirVqaI3iPO+fEEc12RuuRkyRcxmuEBt8x4XxKIPJdMhcKRPug==} engines: {node: '>=8'} peerDependencies: vue: 2.x || 3.x dependencies: - '@sentry/browser': 7.103.0 - '@sentry/core': 7.103.0 - '@sentry/types': 7.103.0 - '@sentry/utils': 7.103.0 - vue: 3.4.21(typescript@5.3.3) + '@sentry/browser': 7.102.0 + '@sentry/core': 7.102.0 + '@sentry/types': 7.102.0 + '@sentry/utils': 7.102.0 + vue: 3.4.19(typescript@5.3.3) dev: false /@sideway/address@4.1.3: @@ -4355,301 +4342,301 @@ packages: defer-to-connect: 1.1.3 dev: true - /@tiptap/core@2.2.4(@tiptap/pm@2.2.4): - resolution: {integrity: sha512-cRrI8IlLIhCE1hacBQzXIC8dsRvGq6a4lYWQK/BaHuZg21CG7szp3Vd8Ix+ra1f5v0xPOT+Hy+QFNQooRMKMCw==} + /@tiptap/core@2.2.3(@tiptap/pm@2.2.3): + resolution: {integrity: sha512-0l3p1/cuaQk8XFf+Ft/ExbUjReGes5Iep7y4nuL/Fzi2S92DZzozY6cosXBHC/Xsqzn6zIkl/gnQTgmTvlmhCQ==} peerDependencies: '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/pm': 2.2.4 + '@tiptap/pm': 2.2.3 dev: false - /@tiptap/extension-blockquote@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-FrfPnn0VgVrUwWLwja1afX99JGLp6PE9ThVcmri+tLwUZQvTTVcCvHoCdOakav3/nge1+aV4iE3tQdyq1tWI9Q==} + /@tiptap/extension-blockquote@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-gN23d/ADhTOB0YIM4lR0VrVczdyaXpmIVYYWZ45tQEVJzFWRSIScE9m9NaVqtqwEMpYHyTHxLth0OQutZ91sog==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-bold@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-v3tTLc8YESFZPOGj5ByFr8VbmQ/PTo49T1vsK50VubxIN/5r9cXlKH8kb3dZlZxCxJa3FrXNO/M8rdGBSWQvSg==} + /@tiptap/extension-bold@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-bHeFkRY5+Nf2DKupstV8EIVn359tw/9MFwDEDoF9F+Sn/vjuS35vm0OqjXYg/Ya9CQvwl/2oym/fKv5kO+Q6og==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-bubble-menu@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): + /@tiptap/extension-bubble-menu@2.2.4(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): resolution: {integrity: sha512-Nx1fS9jcFlhxaTDYlnayz2UulhK6CMaePc36+7PQIVI+u20RhgTCRNr25zKNemvsiM0RPZZVUjlHkxC0l5as1Q==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 tippy.js: 6.3.7 dev: false - /@tiptap/extension-bullet-list@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-z/MPmW8bhRougMuorl6MAQBXeK4rhlP+jBWlNwT+CT8h5IkXqPnDbM1sZeagp2nYfVV6Yc4RWpzimqHHtGnYTA==} + /@tiptap/extension-bullet-list@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-BpYg1pIfLE+2LTC90ts53deEWGSmAojhM/jJ84U19qfbfXt/7/KHrZJ4SAMxJSW3pLpy0bIq2XuOuvppOYVR5g==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-code-block-lowlight@2.2.4(@tiptap/core@2.2.4)(@tiptap/extension-code-block@2.1.12)(@tiptap/pm@2.2.4): - resolution: {integrity: sha512-FxrpY2Lj6kV6pu5LcaeccE3lqOqvOyFSfMGRV6x1OGOMV9TIFJKIVEIcEhqoiqEnuJZzSmQSx7QZqzOvquZo+A==} + /@tiptap/extension-code-block-lowlight@2.2.3(@tiptap/core@2.2.3)(@tiptap/extension-code-block@2.1.12)(@tiptap/pm@2.2.3): + resolution: {integrity: sha512-zVd1Uq0lenbPhw0Mc4ZkrwPblaUp/lNQXGZ8ukhZYQ/JD1oWRA9s0hWQ8jqMi2hp1uTmH5vYFe5bOYqFpoL14g==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/extension-code-block': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/extension-code-block': 2.1.12(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/extension-code-block': 2.1.12(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 dev: false - /@tiptap/extension-code-block@2.1.12(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): + /@tiptap/extension-code-block@2.1.12(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): resolution: {integrity: sha512-RXtSYCVsnk8D+K80uNZShClfZjvv1EgO42JlXLVGWQdIgaNyuOv/6I/Jdf+ZzhnpsBnHufW+6TJjwP5vJPSPHA==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 dev: false - /@tiptap/extension-code@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-JB4SJ2mUU/9qXFUf+K5K9szvovnN9AIcCb0f0UlcVBuddKHSqCl3wO3QJgYt44BfQTLMNuyzr+zVqfFd6BNt/g==} + /@tiptap/extension-code@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-ZMp3CrbAV+PVOnPbGmruvlxFENLc+J/Fos8Y4mWvS1nDbrGuu19OKgKimwdzfDBpZVFVnHpEUnDTMBDzDe0hkg==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-document@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-z+05xGK0OFoXV1GL+/8bzcZuWMdMA3+EKwk5c+iziG60VZcvGTF7jBRsZidlu9Oaj0cDwWHCeeo6L9SgSh6i2A==} + /@tiptap/extension-document@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-60Egd9yKb5SzpQlstQAP2A/2a/Qr+A+TblMRKZugrT+NENUhAj6Tx1HxWlblqGu2MsS1iXvQLZ6BQO1jHkL2IQ==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-dropcursor@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): - resolution: {integrity: sha512-IHwkEKmqpqXyJi16h7871NrcIqeyN7I6XRE2qdqi+MhGigVWI8nWHoYbjRKa7K/1uhs5zeRYyDlq5EuZyL6mgA==} + /@tiptap/extension-dropcursor@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): + resolution: {integrity: sha512-SFvxgVX8/l3H+fV1q6dwmVEwlHuGbaKp1pkQb16/cDiWke/AWOBFTGOIVDfulLI5IiRIL7u3uc+Fy7BXrGDqQw==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 dev: false - /@tiptap/extension-floating-menu@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): + /@tiptap/extension-floating-menu@2.2.4(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): resolution: {integrity: sha512-U25l7PEzOmlAPugNRl8t8lqyhQZS6W/+3f92+FdwW9qXju3i62iX/3OGCC3Gv+vybmQ4fbZmMjvl+VDfenNi3A==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 tippy.js: 6.3.7 dev: false - /@tiptap/extension-gapcursor@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): - resolution: {integrity: sha512-Y6htT/RDSqkQ1UwG2Ia+rNVRvxrKPOs3RbqKHPaWr3vbFWwhHyKhMCvi/FqfI3d5pViVHOZQ7jhb5hT/a0BmNw==} + /@tiptap/extension-gapcursor@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): + resolution: {integrity: sha512-zPVpxembkuOQL/eJ5oAjvZ9Tyv480OpViKrNtOsQh+0nZctmWKnfDntMoWBZiSeW1vsGjkeFIckdeEAQ1KbIxA==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 dev: false - /@tiptap/extension-hard-break@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-FPvS57GcqHIeLbPKGJa3gnH30Xw+YB1PXXnAWG2MpnMtc2Vtj1l5xaYYBZB+ADdXLAlU0YMbKhFLQO4+pg1Isg==} + /@tiptap/extension-hard-break@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-P7sP4WBEaQyiiFAswy9lKvaUWUAUwnfTSN3svTAgx0fpU3/ZeVWg+SDi5ve474Ym2oz2eRAr09mNTdWEUsL32Q==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-heading@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-gkq7Ns2FcrOCRq7Q+VRYt5saMt2R9g4REAtWy/jEevJ5UV5vA2AiGnYDmxwAkHutoYU0sAUkjqx37wE0wpamNw==} + /@tiptap/extension-heading@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-7atctuvtwPqIAdnBPOhAMsJZd41UPnWN3CktzgzfsfEoplq/86QR1hGIE4JXVB2wAZDmbnKP9Fe8PCNr7Q8JCQ==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-history@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): - resolution: {integrity: sha512-FDM32XYF5NU4mzh+fJ8w2CyUqv0l2Nl15sd6fOhQkVxSj8t57z+DUXc9ZR3zkH+1RAagYJo/2Gu3e99KpMr0tg==} + /@tiptap/extension-history@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): + resolution: {integrity: sha512-S1TUfLtrasyv4zFNlBL302uYaR4wxqR/T36a4d71c0ozr0PsdVc6/f9lfH4aYw4PmS3fzDwJj0PAJ9bb+qDbPw==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 dev: false - /@tiptap/extension-horizontal-rule@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): - resolution: {integrity: sha512-iCRHjFQQHApWg3R4fkKkJQhWEOdu1Fdc4YEAukdOXPSg3fg36IwjvsMXjt9SYBtVZ+iio3rORCZGXyMvgCH9uw==} + /@tiptap/extension-horizontal-rule@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): + resolution: {integrity: sha512-pc0J0hBcvj9ymJkFau1W/3L+OhB1PQzMjsx4ZWJvxURL8U7zdDqvYvJjfCA0i5Qw2ZuSVXFACGbEVr6NoCMRAw==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 dev: false - /@tiptap/extension-image@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-xOnqZpnP/fAfmK5AKmXplVQdXBtY5AoZ9B+qllH129aLABaDRzl3e14ZRHC8ahQawOmCe6AOCCXYUBXDOlY5Jg==} + /@tiptap/extension-image@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-IkhISPZ++INAQ3RSwjtJkMIinRyY2g8bqfgyLrc6kXNtfxRGLYS+lizvnI5UUO6X4sRgg/FPfqctAz5bqQBGzA==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-italic@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-qIhGNvWnsQswSgEMRA8jQQjxfkOGNAuNWKEVQX9DPoqAUgknT41hQcAMP8L2+OdACpb2jbVMOO5Cy5Dof2L8/w==} + /@tiptap/extension-italic@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-SSsFuRnm4Y4Qnc6EuvmA4iarLCt/sg8qkqCKiNPjDUP5JR8HGESeoYVjQzprLHY8jusT9qoC26TP1Sin5vZmWQ==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-link@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): - resolution: {integrity: sha512-Qsx0cFZm4dxbkToXs5TcXbSoUdicv8db1gV1DYIZdETqjBm4wFjlzCUP7hPHFlvNfeSy1BzAMRt+RpeuiwvxWQ==} + /@tiptap/extension-link@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): + resolution: {integrity: sha512-AKKgkllpj0Po/hi2bVz719OMqyB1nBhKU/Q05yeWVirOYwF2ZwfM4iK2Iab7xWUVhvlyIG3lrWFQL8A30yuqwQ==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 linkifyjs: 4.1.1 dev: false - /@tiptap/extension-list-item@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-lPLKGKsHpM9ClUa8n7GEUn8pG6HCYU0vFruIy3l2t6jZdHkrgBnYtVGMZ13K8UDnj/hlAlccxku0D0P4mA1Vrg==} + /@tiptap/extension-list-item@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-eyfk4f1jOioj+mkIN2m6XQK61MpV0fi17utt8VNx893Td8kS0g7HHuuYMwyjIRtG35ENUaAt7c216JQwnLsrAw==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-ordered-list@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-TpFy140O9Af1JciXt+xwqYUXxcJ6YG8zi/B5UDJujp+FH5sCmlYYBBnWxiFMhVaj6yEmA2eafu1qUkic/1X5Aw==} + /@tiptap/extension-ordered-list@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-YIWpjkHAJN74tY185ZqatlG4+KbXQOdkJpc5cKWqO89gVWLi7+4xwdeeXbTEG64/LOOWS4Q6r1/EJmDy2FCbyA==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-paragraph@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-m1KwyvTNJxsq7StbspbcOhxO4Wk4YpElDbqOouWi+H4c8azdpI5Pn96ZqhFeE9bSyjByg6OcB/wqoJsLbeFWdQ==} + /@tiptap/extension-paragraph@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-4dP+Ecb2iEWW33ckFKjXRnSfEygaFUN19qzc7mUYD8e61ZA8caWL6//uL7DFIz4Q1rchyefbU52gCwTh2P42kQ==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-placeholder@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): - resolution: {integrity: sha512-UL4Fn9T33SoS7vdI3NnSxBJVeGUIgCIutgXZZ5J8CkcRoDIeS78z492z+6J+qGctHwTd0xUL5NzNJI82HfiTdg==} + /@tiptap/extension-placeholder@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): + resolution: {integrity: sha512-Kc+9a/uACY9XBT0uB/qFVpIHm8MzVr0uWA7MCjwDcMneANRLsXEBzWBzyHxRFoNRECfocivV9hQIhuO4i09c9A==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 dev: false - /@tiptap/extension-strike@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-/a2EwQgA+PpG17V2tVRspcrIY0SN3blwcgM7lxdW4aucGkqSKnf7+91dkhQEwCZ//o8kv9mBCyRoCUcGy6S5Xg==} + /@tiptap/extension-strike@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-3wwFk01ociZajRzD08hp4j/4isFUeD6BIkKPDnZeGD5HKPdTOaDciE3dJ3JaZZrRZPPdPV3yMt5hkBOapqEKzQ==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-table-cell@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-Dt3FjNjM1Mh2BgEjvx5+s96DiJpC82BdMtqicO3z/Pk0X1bn70ocMuURNR7upfRYI+9YbE3+3wBk/vY1yf7ydw==} + /@tiptap/extension-table-cell@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-VB+nOMtep9n3g6wU2ISZbBWzru2XIPiYVlyGkclmW3QzeFw3FC8JLY5HDDaSfuBgLL4/Ll17ol9WDkv62jlP/Q==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-table-header@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-epRrB/468yGvKb/n6lW3VXWUpjMp3+mKxGWfsXLQncGb1leRbqkgQgsUUYuIEosk+70bjzz6lbfHKQBz408s3g==} + /@tiptap/extension-table-header@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-tuuGjfmwuSEHbSMqFMG7BsfgL89KUIvUecukesrs10GJXKh96LKPpFk7JeM0rXAOIDiR6DLF8gfhF1a+OlBpWQ==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-table-row@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-VItZ0byY5CVMrcSRrdBjhElHxIq1JQAAli+o3UNYM5rLKHKx4ezeBCUh80wIKvmaAxWsLMs8h/t4crxUE8dyHA==} + /@tiptap/extension-table-row@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-PohdsPNciwD5fN7I0cthOK8204GbYTZVe2YX1S54dCwoTIlzbJiWiFBLlftP0kqveWLTJD4l1CO0tUku39eFEA==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-table@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): - resolution: {integrity: sha512-9aEFitlcSi33I6a8nGXQ2uNBEx0urYw/C9W4Ygl49YiMzLXtXDBTqSIzVpas1KkKOSN8yaOqB2UiQdbtqGV8fw==} + /@tiptap/extension-table@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): + resolution: {integrity: sha512-k5LwCHribSms7e+oxdqB8S7V7F9VAn2HYncDQnnOm8+v09/JfqX1siWGGKaDeZGZ6BAKgOYx0hOf/RSWSTM8og==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 dev: false - /@tiptap/extension-task-item@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): - resolution: {integrity: sha512-Ixzv7bPcgrWelSD0Jy6yAlHxmGWpD5lPt6Ey4POYy7u98duyUFOBMHLcsV24ipQsRacuB+htgmuqOrkiL+hg7w==} + /@tiptap/extension-task-item@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): + resolution: {integrity: sha512-QffmRA56pq4mOb3MnWVOJTiW7NPf54z/iBIlW/8zLKcCKUr8PtC27rs++r5MmtsBrQInRm50b+ibKINyOixd+g==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 dev: false - /@tiptap/extension-task-list@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-URh1Yzj/YZBOMkobK4/U8s1QYwIIqHm4b0YadLPPZx9IzTjyV/2bvIakphCmBtxWxeTXW5TbO9eNod3qatq21w==} + /@tiptap/extension-task-list@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-ruwJ//jPjIT60p42goqqApCYsjZHk+E15HajEycdpu9gOqEiVh/Hsn8z4g3ZYwgMF8SuyU4mm11K05xYtoG40A==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-text@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-NlKHMPnRJXB+0AGtDlU0P2Pg+SdesA2lMMd7JzDUgJgL7pX2jOb8eUqSeOjFKuSzFSqYfH6C3o6mQiNhuQMv+g==} + /@tiptap/extension-text@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-BrWGCkmuzVcsNy7dSCfJyVwedPzeNz6BR/OUNzM8Mqt2KSxfoIRy7cg16HvFB4YW+ijrM9XUqDIFvqYI0TY+Jg==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-typography@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-1gmvr74uk44Wzxd6QI+dKz/M//xaD15yYwUtcRc9+ohbfvCqtRl3XDVoxl3MQmDMljcui5kMMaRcFNvW1Kujvg==} + /@tiptap/extension-typography@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-PCxb5lJkx/OguqgnrrhKdM8ayeH2EKrcCbbCMTScLEYSVKs0nkTt7p+PwugsZW5hxeuwhIOKgLSPHE4tSYol9w==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/extension-underline@2.2.4(@tiptap/core@2.2.4): - resolution: {integrity: sha512-jCHgIJMwtXlGHVy/j3L8/QvglHCikkHJw7YS5yf8E/8HlPh1tZfVy/IxdgacDOpUN30X+UPJZQDdVKymafgwdA==} + /@tiptap/extension-underline@2.2.3(@tiptap/core@2.2.3): + resolution: {integrity: sha512-Y6PTaXmDFay39+Knk77T+Ezc5vuC/gFxZFD6cQhjctZHMJ2QMAguMKWtBVaSs78HBkKnwTU9EViAFBurz++Geg==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) dev: false - /@tiptap/pm@2.2.4: - resolution: {integrity: sha512-Po0klR165zgtinhVp1nwMubjyKx6gAY9kH3IzcniYLCkqhPgiqnAcCr61TBpp4hfK8YURBS4ihvCB1dyfCyY8A==} + /@tiptap/pm@2.2.3: + resolution: {integrity: sha512-jYZX+0fjN+a1J8qY72Poz1LK6X6oHVQkJIq6qzcx3rm0voYZNVRzP2GIfzstncZiEqRXABHY3mWfOi2I4K9tQA==} dependencies: prosemirror-changeset: 2.2.1 prosemirror-collab: 1.3.1 @@ -4671,28 +4658,28 @@ packages: prosemirror-view: 1.32.7 dev: false - /@tiptap/suggestion@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): - resolution: {integrity: sha512-g6HHsKM6K3asW+ZlwMYyLCRqCRaswoliZOQofY4iZt5ru5HNTSzm3YW4XSyW5RGXJIuc319yyrOFgtJ3Fyu5rQ==} + /@tiptap/suggestion@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): + resolution: {integrity: sha512-pMInbk8+rYNaCz4oT/uS498mxSGIJXU32mkXv7wdDqMT2nnZQ2AHtJDUtMuB1RX+DS4ll9vdzrKqQHSW5t2ybQ==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 dev: false - /@tiptap/vue-3@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4)(vue@3.4.21): - resolution: {integrity: sha512-6Rue56OUmDl/OT07QcLsH1UvYGUmV8OFSDCrLrUyku/2lAYHwHz6+KhAB5paZt70nEGIw03G1KCT074negj6NQ==} + /@tiptap/vue-3@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3)(vue@3.4.19): + resolution: {integrity: sha512-TC+pncpxP6GHgM+qvX/1mfT+Xl3OlEekZqjetNJC/MfFM55OL5dIEu5kVjOiRsGQ/TWgwBGPrRYEE0Y1D6FuBA==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 vue: ^3.0.0 dependencies: - '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) - '@tiptap/extension-bubble-menu': 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) - '@tiptap/extension-floating-menu': 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) - '@tiptap/pm': 2.2.4 - vue: 3.4.21(typescript@5.3.3) + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/extension-bubble-menu': 2.2.4(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) + '@tiptap/extension-floating-menu': 2.2.4(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) + '@tiptap/pm': 2.2.3 + vue: 3.4.19(typescript@5.3.3) dev: false /@tootallnate/once@2.0.0: @@ -4759,7 +4746,7 @@ packages: /@types/fs-extra@9.0.13: resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} dependencies: - '@types/node': 20.11.22 + '@types/node': 20.11.10 dev: true /@types/har-format@1.2.10: @@ -4783,7 +4770,7 @@ packages: /@types/keyv@3.1.3: resolution: {integrity: sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==} dependencies: - '@types/node': 20.11.22 + '@types/node': 20.11.10 dev: true /@types/linkify-it@3.0.2: @@ -4824,8 +4811,8 @@ packages: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} dev: true - /@types/node@20.11.22: - resolution: {integrity: sha512-/G+IxWxma6V3E+pqK1tSl2Fo1kl41pK1yeCyDsgkF9WlVAme4j5ISYM2zR11bgLFJGLN5sVK40T4RJNuiZbEjA==} + /@types/node@20.11.10: + resolution: {integrity: sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg==} dependencies: undici-types: 5.26.5 dev: true @@ -4845,20 +4832,20 @@ packages: /@types/postcss-preset-env@7.7.0: resolution: {integrity: sha512-biD8MwSiZo1Nztn1cIBPMcKNKzgFyU05AB96HIF9y3G4f9vdx2O60DHCSpWXChTp6mOEGu15fqIw2DetVVjghw==} dependencies: - autoprefixer: 10.4.17(postcss@8.4.35) - postcss: 8.4.35 + autoprefixer: 10.4.17(postcss@8.4.33) + postcss: 8.4.33 dev: true /@types/resolve@1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} dependencies: - '@types/node': 20.11.22 + '@types/node': 20.11.10 dev: true /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 20.11.22 + '@types/node': 20.11.10 dev: true /@types/semver@7.5.0: @@ -4873,8 +4860,8 @@ packages: resolution: {integrity: sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==} dev: true - /@types/sortablejs@1.15.8: - resolution: {integrity: sha512-b79830lW+RZfwaztgs1aVPgbasJ8e7AXtZYHTELNXZPsERt4ymJdjV4OccDbHQAvHrCcFpbF78jkm0R6h/pZVg==} + /@types/sortablejs@1.15.7: + resolution: {integrity: sha512-PvgWCx1Lbgm88FdQ6S7OGvLIjWS66mudKPlfdrWil0TjsO5zmoZmzoKiiwRShs1dwPgrlkr0N4ewuy0/+QUXYQ==} dev: true /@types/tern@0.23.4: @@ -4907,11 +4894,11 @@ packages: resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} requiresBuild: true dependencies: - '@types/node': 20.11.22 + '@types/node': 20.11.10 dev: true optional: true - /@typescript-eslint/eslint-plugin@6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.57.0)(typescript@5.3.3): + /@typescript-eslint/eslint-plugin@6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.56.0)(typescript@5.3.3): resolution: {integrity: sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -4923,25 +4910,25 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.6.2 - '@typescript-eslint/parser': 6.20.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.20.0(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/scope-manager': 6.20.0 - '@typescript-eslint/type-utils': 6.20.0(eslint@8.57.0)(typescript@5.3.3) - '@typescript-eslint/utils': 6.20.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/type-utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.20.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + eslint: 8.56.0 graphemer: 1.4.0 ignore: 5.2.4 natural-compare: 1.4.0 - semver: 7.5.4 + semver: 7.6.0 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/eslint-plugin@7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3): - resolution: {integrity: sha512-j6vT/kCulhG5wBmGtstKeiVr1rdXE4nk+DT1k6trYkwlrvW9eOF5ZbgKnd/YR6PcM4uTEXa0h6Fcvf6X7Dxl0w==} + /@typescript-eslint/eslint-plugin@7.0.1(@typescript-eslint/parser@7.0.1)(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-OLvgeBv3vXlnnJGIAgCLYKjgMEU+wBGj07MQ/nxAaON+3mLzX7mJbhRYrVGiVvFiXtwFlkcBa/TtmglHy0UbzQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -4952,24 +4939,24 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.6.2 - '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3) - '@typescript-eslint/scope-manager': 7.1.0 - '@typescript-eslint/type-utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3) - '@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 7.1.0 + '@typescript-eslint/parser': 7.0.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 7.0.1 + '@typescript-eslint/type-utils': 7.0.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/utils': 7.0.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 7.0.1 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + eslint: 8.56.0 graphemer: 1.4.0 ignore: 5.2.4 natural-compare: 1.4.0 - semver: 7.5.4 + semver: 7.6.0 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.3.3): + /@typescript-eslint/parser@6.20.0(eslint@8.56.0)(typescript@5.3.3): resolution: {integrity: sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -4984,14 +4971,14 @@ packages: '@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.20.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + eslint: 8.56.0 typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3): - resolution: {integrity: sha512-V1EknKUubZ1gWFjiOZhDSNToOjs63/9O0puCgGS8aDOgpZY326fzFu15QAUjwaXzRZjf/qdsdBrckYdv9YxB8w==} + /@typescript-eslint/parser@7.0.1(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-8GcRRZNzaHxKzBPU3tKtFNing571/GwPBeCvmAUw0yBtfE2XVd0zFKJIMSWkHJcPQi0ekxjIts6L/rrZq5cxGQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^8.56.0 @@ -5000,12 +4987,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 7.1.0 - '@typescript-eslint/types': 7.1.0 - '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 7.1.0 + '@typescript-eslint/scope-manager': 7.0.1 + '@typescript-eslint/types': 7.0.1 + '@typescript-eslint/typescript-estree': 7.0.1(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 7.0.1 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + eslint: 8.56.0 typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -5019,15 +5006,15 @@ packages: '@typescript-eslint/visitor-keys': 6.20.0 dev: true - /@typescript-eslint/scope-manager@7.1.0: - resolution: {integrity: sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==} + /@typescript-eslint/scope-manager@7.0.1: + resolution: {integrity: sha512-v7/T7As10g3bcWOOPAcbnMDuvctHzCFYCG/8R4bK4iYzdFqsZTbXGln0cZNVcwQcwewsYU2BJLay8j0/4zOk4w==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 7.1.0 - '@typescript-eslint/visitor-keys': 7.1.0 + '@typescript-eslint/types': 7.0.1 + '@typescript-eslint/visitor-keys': 7.0.1 dev: true - /@typescript-eslint/type-utils@6.20.0(eslint@8.57.0)(typescript@5.3.3): + /@typescript-eslint/type-utils@6.20.0(eslint@8.56.0)(typescript@5.3.3): resolution: {integrity: sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -5038,17 +5025,17 @@ packages: optional: true dependencies: '@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3) - '@typescript-eslint/utils': 6.20.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3) debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + eslint: 8.56.0 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/type-utils@7.1.0(eslint@8.57.0)(typescript@5.3.3): - resolution: {integrity: sha512-UZIhv8G+5b5skkcuhgvxYWHjk7FW7/JP5lPASMEUoliAPwIH/rxoUSQPia2cuOj9AmDZmwUl1usKm85t5VUMew==} + /@typescript-eslint/type-utils@7.0.1(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-YtT9UcstTG5Yqy4xtLiClm1ZpM/pWVGFnkAa90UfdkkZsR1eP2mR/1jbHeYp8Ay1l1JHPyGvoUYR6o3On5Nhmw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^8.56.0 @@ -5057,10 +5044,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3) - '@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/typescript-estree': 7.0.1(typescript@5.3.3) + '@typescript-eslint/utils': 7.0.1(eslint@8.56.0)(typescript@5.3.3) debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + eslint: 8.56.0 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: @@ -5072,8 +5059,8 @@ packages: engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/types@7.1.0: - resolution: {integrity: sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==} + /@typescript-eslint/types@7.0.1: + resolution: {integrity: sha512-uJDfmirz4FHib6ENju/7cz9SdMSkeVvJDK3VcMFvf/hAShg8C74FW+06MaQPODHfDJp/z/zHfgawIJRjlu0RLg==} engines: {node: ^16.0.0 || >=18.0.0} dev: true @@ -5092,15 +5079,15 @@ packages: globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.5.4 + semver: 7.6.0 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/typescript-estree@7.1.0(typescript@5.3.3): - resolution: {integrity: sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==} + /@typescript-eslint/typescript-estree@7.0.1(typescript@5.3.3): + resolution: {integrity: sha512-SO9wHb6ph0/FN5OJxH4MiPscGah5wjOd0RRpaLvuBv9g8565Fgu0uMySFEPqwPHiQU90yzJ2FjRYKGrAhS1xig==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -5108,52 +5095,52 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 7.1.0 - '@typescript-eslint/visitor-keys': 7.1.0 + '@typescript-eslint/types': 7.0.1 + '@typescript-eslint/visitor-keys': 7.0.1 debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.5.4 + semver: 7.6.0 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@6.20.0(eslint@8.57.0)(typescript@5.3.3): + /@typescript-eslint/utils@6.20.0(eslint@8.56.0)(typescript@5.3.3): resolution: {integrity: sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.0 '@typescript-eslint/scope-manager': 6.20.0 '@typescript-eslint/types': 6.20.0 '@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3) - eslint: 8.57.0 - semver: 7.5.4 + eslint: 8.56.0 + semver: 7.6.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/utils@7.1.0(eslint@8.57.0)(typescript@5.3.3): - resolution: {integrity: sha512-WUFba6PZC5OCGEmbweGpnNJytJiLG7ZvDBJJoUcX4qZYf1mGZ97mO2Mps6O2efxJcJdRNpqweCistDbZMwIVHw==} + /@typescript-eslint/utils@7.0.1(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-oe4his30JgPbnv+9Vef1h48jm0S6ft4mNwi9wj7bX10joGn07QRfqIqFHoMiajrtoU88cIhXf8ahwgrcbNLgPA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^8.56.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 7.1.0 - '@typescript-eslint/types': 7.1.0 - '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3) - eslint: 8.57.0 - semver: 7.5.4 + '@typescript-eslint/scope-manager': 7.0.1 + '@typescript-eslint/types': 7.0.1 + '@typescript-eslint/typescript-estree': 7.0.1(typescript@5.3.3) + eslint: 8.56.0 + semver: 7.6.0 transitivePeerDependencies: - supports-color - typescript @@ -5167,11 +5154,11 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@typescript-eslint/visitor-keys@7.1.0: - resolution: {integrity: sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==} + /@typescript-eslint/visitor-keys@7.0.1: + resolution: {integrity: sha512-hwAgrOyk++RTXrP4KzCg7zB2U0xt7RUU0ZdMSCsqF3eKUwkdXUMyTb0qdCuji7VIbcpG62kKTU9M1J1c9UpFBw==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 7.1.0 + '@typescript-eslint/types': 7.0.1 eslint-visitor-keys: 3.4.3 dev: true @@ -5179,8 +5166,8 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@vitejs/plugin-legacy@5.3.1(esbuild@0.20.1)(terser@5.24.0)(vite@5.1.4): - resolution: {integrity: sha512-ymCuZo8Bu7gSO85I3E/3SNnaQ64gFdVpTqxqhl8YeasJChDxN8D3IKYByC+AsxwoeO2AE59wy4PPILM/A03TIQ==} + /@vitejs/plugin-legacy@5.3.0(esbuild@0.20.0)(terser@5.24.0)(vite@5.0.12): + resolution: {integrity: sha512-BhW+WcJmEgW5G/1UQRiVQ7wz9/ZPnxqzExT9n0zAk4RlqQQ/26udIeXzdU8+03AGnaF61wmZlCspexgEnxFWMA==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: terser: ^5.4.0 @@ -5188,62 +5175,62 @@ packages: dependencies: '@babel/core': 7.23.9 '@babel/preset-env': 7.23.9(@babel/core@7.23.9) - browserslist: 4.23.0 + browserslist: 4.22.3 core-js: 3.36.0 - esbuild-plugin-browserslist: 0.11.1(browserslist@4.23.0)(esbuild@0.20.1) + esbuild-plugin-browserslist: 0.10.0(browserslist@4.22.3)(esbuild@0.20.0) magic-string: 0.30.7 regenerator-runtime: 0.14.1 systemjs: 6.14.3 terser: 5.24.0 - vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) transitivePeerDependencies: - esbuild - supports-color dev: true - /@vitejs/plugin-vue@5.0.4(vite@5.1.4)(vue@3.4.21): - resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==} + /@vitejs/plugin-vue@5.0.3(vite@5.0.12)(vue@3.4.19): + resolution: {integrity: sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 vue: ^3.2.25 dependencies: - vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) - vue: 3.4.21(typescript@5.3.3) + vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vue: 3.4.19(typescript@5.3.3) dev: true - /@vitest/expect@1.3.1: - resolution: {integrity: sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==} + /@vitest/expect@1.2.2: + resolution: {integrity: sha512-3jpcdPAD7LwHUUiT2pZTj2U82I2Tcgg2oVPvKxhn6mDI2On6tfvPQTjAI4628GUGDZrCm4Zna9iQHm5cEexOAg==} dependencies: - '@vitest/spy': 1.3.1 - '@vitest/utils': 1.3.1 + '@vitest/spy': 1.2.2 + '@vitest/utils': 1.2.2 chai: 4.3.10 dev: true - /@vitest/runner@1.3.1: - resolution: {integrity: sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg==} + /@vitest/runner@1.2.2: + resolution: {integrity: sha512-JctG7QZ4LSDXr5CsUweFgcpEvrcxOV1Gft7uHrvkQ+fsAVylmWQvnaAr/HDp3LAH1fztGMQZugIheTWjaGzYIg==} dependencies: - '@vitest/utils': 1.3.1 + '@vitest/utils': 1.2.2 p-limit: 5.0.0 pathe: 1.1.1 dev: true - /@vitest/snapshot@1.3.1: - resolution: {integrity: sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ==} + /@vitest/snapshot@1.2.2: + resolution: {integrity: sha512-SmGY4saEw1+bwE1th6S/cZmPxz/Q4JWsl7LvbQIky2tKE35US4gd0Mjzqfr84/4OD0tikGWaWdMja/nWL5NIPA==} dependencies: magic-string: 0.30.7 pathe: 1.1.1 pretty-format: 29.7.0 dev: true - /@vitest/spy@1.3.1: - resolution: {integrity: sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==} + /@vitest/spy@1.2.2: + resolution: {integrity: sha512-k9Gcahssw8d7X3pSLq3e3XEu/0L78mUkCjivUqCQeXJm9clfXR/Td8+AP+VC1O6fKPIDLcHDTAmBOINVuv6+7g==} dependencies: tinyspy: 2.2.0 dev: true - /@vitest/utils@1.3.1: - resolution: {integrity: sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==} + /@vitest/utils@1.2.2: + resolution: {integrity: sha512-WKITBHLsBHlpjnDQahr+XK6RE7MiAsgrIkr0pGhQ9ygoxBfUeG0lUG5iLlzqjmKSlBv3+j5EGsriBzh+C3Tq9g==} dependencies: diff-sequences: 29.6.3 estree-walker: 3.0.3 @@ -5289,11 +5276,11 @@ packages: source-map-js: 1.0.2 dev: true - /@vue/compiler-core@3.4.21: - resolution: {integrity: sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==} + /@vue/compiler-core@3.4.19: + resolution: {integrity: sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==} dependencies: '@babel/parser': 7.23.9 - '@vue/shared': 3.4.21 + '@vue/shared': 3.4.19 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.0.2 @@ -5312,11 +5299,11 @@ packages: '@vue/shared': 3.4.14 dev: true - /@vue/compiler-dom@3.4.21: - resolution: {integrity: sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==} + /@vue/compiler-dom@3.4.19: + resolution: {integrity: sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==} dependencies: - '@vue/compiler-core': 3.4.21 - '@vue/shared': 3.4.21 + '@vue/compiler-core': 3.4.19 + '@vue/shared': 3.4.19 /@vue/compiler-sfc@3.3.13: resolution: {integrity: sha512-DQVmHEy/EKIgggvnGRLx21hSqnr1smUS9Aq8tfxiiot8UR0/pXKHN9k78/qQ7etyQTFj5em5nruODON7dBeumw==} @@ -5329,21 +5316,21 @@ packages: '@vue/shared': 3.3.13 estree-walker: 2.0.2 magic-string: 0.30.7 - postcss: 8.4.35 + postcss: 8.4.33 source-map-js: 1.0.2 dev: false - /@vue/compiler-sfc@3.4.21: - resolution: {integrity: sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==} + /@vue/compiler-sfc@3.4.19: + resolution: {integrity: sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==} dependencies: '@babel/parser': 7.23.9 - '@vue/compiler-core': 3.4.21 - '@vue/compiler-dom': 3.4.21 - '@vue/compiler-ssr': 3.4.21 - '@vue/shared': 3.4.21 + '@vue/compiler-core': 3.4.19 + '@vue/compiler-dom': 3.4.19 + '@vue/compiler-ssr': 3.4.19 + '@vue/shared': 3.4.19 estree-walker: 2.0.2 magic-string: 0.30.7 - postcss: 8.4.35 + postcss: 8.4.33 source-map-js: 1.0.2 /@vue/compiler-ssr@3.3.13: @@ -5353,11 +5340,11 @@ packages: '@vue/shared': 3.3.13 dev: false - /@vue/compiler-ssr@3.4.21: - resolution: {integrity: sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==} + /@vue/compiler-ssr@3.4.19: + resolution: {integrity: sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==} dependencies: - '@vue/compiler-dom': 3.4.21 - '@vue/shared': 3.4.21 + '@vue/compiler-dom': 3.4.19 + '@vue/shared': 3.4.19 /@vue/devtools-api@6.5.0: resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} @@ -5367,7 +5354,7 @@ packages: resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==} dev: false - /@vue/eslint-config-typescript@12.0.0(eslint-plugin-vue@9.22.0)(eslint@8.57.0)(typescript@5.3.3): + /@vue/eslint-config-typescript@12.0.0(eslint-plugin-vue@9.20.1)(eslint@8.56.0)(typescript@5.3.3): resolution: {integrity: sha512-StxLFet2Qe97T8+7L8pGlhYBBr8Eg05LPuTDVopQV6il+SK6qqom59BA/rcFipUef2jD8P2X44Vd8tMFytfvlg==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: @@ -5378,12 +5365,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.57.0)(typescript@5.3.3) - '@typescript-eslint/parser': 6.20.0(eslint@8.57.0)(typescript@5.3.3) - eslint: 8.57.0 - eslint-plugin-vue: 9.22.0(eslint@8.57.0) + '@typescript-eslint/eslint-plugin': 6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.20.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-plugin-vue: 9.20.1(eslint@8.56.0) typescript: 5.3.3 - vue-eslint-parser: 9.3.1(eslint@8.57.0) + vue-eslint-parser: 9.3.1(eslint@8.56.0) transitivePeerDependencies: - supports-color dev: true @@ -5418,32 +5405,32 @@ packages: magic-string: 0.30.7 dev: false - /@vue/reactivity@3.4.21: - resolution: {integrity: sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==} + /@vue/reactivity@3.4.19: + resolution: {integrity: sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==} dependencies: - '@vue/shared': 3.4.21 + '@vue/shared': 3.4.19 - /@vue/runtime-core@3.4.21: - resolution: {integrity: sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==} + /@vue/runtime-core@3.4.19: + resolution: {integrity: sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==} dependencies: - '@vue/reactivity': 3.4.21 - '@vue/shared': 3.4.21 + '@vue/reactivity': 3.4.19 + '@vue/shared': 3.4.19 - /@vue/runtime-dom@3.4.21: - resolution: {integrity: sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==} + /@vue/runtime-dom@3.4.19: + resolution: {integrity: sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==} dependencies: - '@vue/runtime-core': 3.4.21 - '@vue/shared': 3.4.21 + '@vue/runtime-core': 3.4.19 + '@vue/shared': 3.4.19 csstype: 3.1.3 - /@vue/server-renderer@3.4.21(vue@3.4.21): - resolution: {integrity: sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==} + /@vue/server-renderer@3.4.19(vue@3.4.19): + resolution: {integrity: sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==} peerDependencies: - vue: 3.4.21 + vue: 3.4.19 dependencies: - '@vue/compiler-ssr': 3.4.21 - '@vue/shared': 3.4.21 - vue: 3.4.21(typescript@5.3.3) + '@vue/compiler-ssr': 3.4.19 + '@vue/shared': 3.4.19 + vue: 3.4.19(typescript@5.3.3) /@vue/shared@3.3.13: resolution: {integrity: sha512-/zYUwiHD8j7gKx2argXEMCUXVST6q/21DFU0sTfNX0URJroCe3b1UF6vLJ3lQDfLNIiiRl2ONp7Nh5UVWS6QnA==} @@ -5453,10 +5440,10 @@ packages: resolution: {integrity: sha512-nmi3BtLpvqXAWoRZ6HQ+pFJOHBU4UnH3vD3opgmwXac7vhaHKA9nj1VeGjMggdB9eLtW83eHyPCmOU1qzdsC7Q==} dev: true - /@vue/shared@3.4.21: - resolution: {integrity: sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==} + /@vue/shared@3.4.19: + resolution: {integrity: sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==} - /@vue/test-utils@2.4.4(vue@3.4.21): + /@vue/test-utils@2.4.4(vue@3.4.19): resolution: {integrity: sha512-8jkRxz8pNhClAf4Co4ZrpAoFISdvT3nuSkUlY6Ys6rmTpw3DMWG/X3mw3gQ7QJzgCZO9f+zuE2kW57fi09MW7Q==} peerDependencies: '@vue/server-renderer': ^3.0.1 @@ -5466,7 +5453,7 @@ packages: optional: true dependencies: js-beautify: 1.14.9 - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) vue-component-type-helpers: 1.8.22 dev: true @@ -5474,64 +5461,64 @@ packages: resolution: {integrity: sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==} dev: true - /@vueuse/core@10.9.0(vue@3.4.21): - resolution: {integrity: sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==} + /@vueuse/core@10.8.0(vue@3.4.19): + resolution: {integrity: sha512-G9Ok9fjx10TkNIPn8V1dJmK1NcdJCtYmDRyYiTMUyJ1p0Tywc1zmOoCQ2xhHYyz8ULBU4KjIJQ9n+Lrty74iVw==} dependencies: '@types/web-bluetooth': 0.0.20 - '@vueuse/metadata': 10.9.0 - '@vueuse/shared': 10.9.0(vue@3.4.21) - vue-demi: 0.14.7(vue@3.4.21) + '@vueuse/metadata': 10.8.0 + '@vueuse/shared': 10.8.0(vue@3.4.19) + vue-demi: 0.14.7(vue@3.4.19) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/core@9.13.0(vue@3.4.21): + /@vueuse/core@9.13.0(vue@3.4.19): resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==} dependencies: '@types/web-bluetooth': 0.0.16 '@vueuse/metadata': 9.13.0 - '@vueuse/shared': 9.13.0(vue@3.4.21) - vue-demi: 0.14.6(vue@3.4.21) + '@vueuse/shared': 9.13.0(vue@3.4.19) + vue-demi: 0.14.6(vue@3.4.19) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/metadata@10.9.0: - resolution: {integrity: sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==} + /@vueuse/metadata@10.8.0: + resolution: {integrity: sha512-Nim/Vle5OgXcXhAvGOgkJQXB1Yb+Kq/fMbLuv3YYDYbiQrwr39ljuD4k9fPeq4yUyokYRo2RaNQmbbIMWB/9+w==} dev: false /@vueuse/metadata@9.13.0: resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==} dev: false - /@vueuse/router@10.9.0(vue-router@4.3.0)(vue@3.4.21): - resolution: {integrity: sha512-MOmrCMQlRuPS4PExE1hy8T0XbZUXaNbEuh7CAG5mC8kdvdgANQMkdvJ7vIEOP27n5mXK/4YjvXJOZSsur4E0QQ==} + /@vueuse/router@10.8.0(vue-router@4.3.0)(vue@3.4.19): + resolution: {integrity: sha512-5WI5QYEs2XLC01JGrOC8dMDAkNsp3rOvvwed2O2gHUQt/OQ3cu3wLu8RfI0CZfoetDrj/LDcIYDcGhh70ST6+Q==} peerDependencies: vue-router: '>=4.0.0-rc.1' dependencies: - '@vueuse/shared': 10.9.0(vue@3.4.21) - vue-demi: 0.14.7(vue@3.4.21) - vue-router: 4.3.0(vue@3.4.21) + '@vueuse/shared': 10.8.0(vue@3.4.19) + vue-demi: 0.14.7(vue@3.4.19) + vue-router: 4.3.0(vue@3.4.19) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/shared@10.9.0(vue@3.4.21): - resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==} + /@vueuse/shared@10.8.0(vue@3.4.19): + resolution: {integrity: sha512-dUdy6zwHhULGxmr9YUg8e+EnB39gcM4Fe2oKBSrh3cOsV30JcMPtsyuspgFCUo5xxFNaeMf/W2yyKfST7Bg8oQ==} dependencies: - vue-demi: 0.14.7(vue@3.4.21) + vue-demi: 0.14.7(vue@3.4.19) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/shared@9.13.0(vue@3.4.21): + /@vueuse/shared@9.13.0(vue@3.4.19): resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} dependencies: - vue-demi: 0.14.6(vue@3.4.21) + vue-demi: 0.14.6(vue@3.4.19) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -5713,19 +5700,19 @@ packages: engines: {node: '>= 4.0.0'} dev: true - /autoprefixer@10.4.17(postcss@8.4.35): + /autoprefixer@10.4.17(postcss@8.4.33): resolution: {integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: - browserslist: 4.23.0 - caniuse-lite: 1.0.30001591 + browserslist: 4.22.3 + caniuse-lite: 1.0.30001581 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.35 + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true @@ -5897,15 +5884,15 @@ packages: dependencies: fill-range: 7.0.1 - /browserslist@4.23.0: - resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + /browserslist@4.22.3: + resolution: {integrity: sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001591 + caniuse-lite: 1.0.30001581 electron-to-chromium: 1.4.685 node-releases: 2.0.14 - update-browserslist-db: 1.0.13(browserslist@4.23.0) + update-browserslist-db: 1.0.13(browserslist@4.22.3) dev: true /buffer-crc32@0.2.13: @@ -5988,8 +5975,8 @@ packages: engines: {node: '>=6'} dev: true - /caniuse-lite@1.0.30001591: - resolution: {integrity: sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==} + /caniuse-lite@1.0.30001581: + resolution: {integrity: sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ==} dev: true /capital-case@1.0.4: @@ -6309,7 +6296,7 @@ packages: /core-js-compat@3.34.0: resolution: {integrity: sha512-4ZIyeNbW/Cn1wkMMDy+mvrRUxrwFNjKwbhCfQpDd+eLgYipDqp8oGFGtLmhh18EDPKA0g3VUBYOxQGGwvWLVpA==} dependencies: - browserslist: 4.23.0 + browserslist: 4.22.3 dev: true /core-js@3.36.0: @@ -6346,35 +6333,35 @@ packages: engines: {node: '>=8'} dev: true - /css-blank-pseudo@6.0.1(postcss@8.4.35): + /css-blank-pseudo@6.0.1(postcss@8.4.33): resolution: {integrity: sha512-goSnEITByxTzU4Oh5oJZrEWudxTqk7L6IXj1UW69pO6Hv0UdX+Vsrt02FFu5DweRh2bLu6WpX/+zsQCu5O1gKw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 - postcss-selector-parser: 6.0.13 + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 dev: true - /css-has-pseudo@6.0.2(postcss@8.4.35): - resolution: {integrity: sha512-Z2Qm5yyOvJRTy6THdUlnGIX6PW/1wOc4FHWlfkcBkfkpZ3oz6lPdG+h+J7t1HZHT4uSSVR8XatXiMpqMUADXow==} + /css-has-pseudo@6.0.1(postcss@8.4.33): + resolution: {integrity: sha512-WwoVKqNxApfEI7dWFyaHoeFCcUPD+lPyjL6lNpRUNX7IyIUuVpawOTwwA5D0ZR6V2xQZonNPVj8kEcxzEaAQfQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.13) - postcss: 8.4.35 - postcss-selector-parser: 6.0.13 + '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.15) + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 postcss-value-parser: 4.2.0 dev: true - /css-prefers-color-scheme@9.0.1(postcss@8.4.35): + /css-prefers-color-scheme@9.0.1(postcss@8.4.33): resolution: {integrity: sha512-iFit06ochwCKPRiWagbTa1OAWCvWWVdEnIFd8BaRrgO8YrrNh4RAWUQTFcYX5tdFZgFl1DJ3iiULchZyEbnF4g==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 dev: true /css-select@4.2.1: @@ -6458,8 +6445,8 @@ packages: /csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - /cypress@13.6.6: - resolution: {integrity: sha512-S+2S9S94611hXimH9a3EAYt81QM913ZVA03pUmGDfLTFa5gyp85NJ8dJGSlEAEmyRsYkioS1TtnWtbv/Fzt11A==} + /cypress@13.6.3: + resolution: {integrity: sha512-d/pZvgwjAyZsoyJ3FOsJT5lDsqnxQ/clMqnNc++rkHjbkkiF2h9s0JsZSyyH4QXhVFW3zPFg82jD25roFLOdZA==} engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} hasBin: true requiresBuild: true @@ -6501,7 +6488,7 @@ packages: process: 0.11.10 proxy-from-env: 1.0.0 request-progress: 3.0.0 - semver: 7.5.4 + semver: 7.6.0 supports-color: 8.1.1 tmp: 0.2.1 untildify: 4.0.0 @@ -6883,16 +6870,16 @@ packages: is-symbol: 1.0.4 dev: true - /esbuild-plugin-browserslist@0.11.1(browserslist@4.23.0)(esbuild@0.20.1): - resolution: {integrity: sha512-yNdZRdDBEbm0PT4q2bJBhXvnwakXG5mG8ipiwGe5SRDPnKa7L7kQm2tHuBMowBtcFz6kRtZTv5njK7PJwU+tCQ==} + /esbuild-plugin-browserslist@0.10.0(browserslist@4.22.3)(esbuild@0.20.0): + resolution: {integrity: sha512-rZWFcp3l+73xDiJB+Vl9UqP1VVs+L4E0lygbwJl6UTmW2qQago7DLT56hBu0vocH/TtZsAcRHj0+qHqkkB5Gww==} engines: {node: '>=18'} peerDependencies: browserslist: ^4.21.8 - esbuild: ~0.20.0 + esbuild: ~0.19.2 dependencies: - browserslist: 4.23.0 + browserslist: 4.22.3 debug: 4.3.4(supports-color@8.1.1) - esbuild: 0.20.1 + esbuild: 0.20.0 zod: 3.22.4 transitivePeerDependencies: - supports-color @@ -6929,35 +6916,35 @@ packages: '@esbuild/win32-x64': 0.19.12 dev: true - /esbuild@0.20.1: - resolution: {integrity: sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA==} + /esbuild@0.20.0: + resolution: {integrity: sha512-6iwE3Y2RVYCME1jLpBqq7LQWK3MW6vjV2bZy6gt/WrqkY+WE74Spyc0ThAOYpMtITvnjX09CrC6ym7A/m9mebA==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/aix-ppc64': 0.20.1 - '@esbuild/android-arm': 0.20.1 - '@esbuild/android-arm64': 0.20.1 - '@esbuild/android-x64': 0.20.1 - '@esbuild/darwin-arm64': 0.20.1 - '@esbuild/darwin-x64': 0.20.1 - '@esbuild/freebsd-arm64': 0.20.1 - '@esbuild/freebsd-x64': 0.20.1 - '@esbuild/linux-arm': 0.20.1 - '@esbuild/linux-arm64': 0.20.1 - '@esbuild/linux-ia32': 0.20.1 - '@esbuild/linux-loong64': 0.20.1 - '@esbuild/linux-mips64el': 0.20.1 - '@esbuild/linux-ppc64': 0.20.1 - '@esbuild/linux-riscv64': 0.20.1 - '@esbuild/linux-s390x': 0.20.1 - '@esbuild/linux-x64': 0.20.1 - '@esbuild/netbsd-x64': 0.20.1 - '@esbuild/openbsd-x64': 0.20.1 - '@esbuild/sunos-x64': 0.20.1 - '@esbuild/win32-arm64': 0.20.1 - '@esbuild/win32-ia32': 0.20.1 - '@esbuild/win32-x64': 0.20.1 + '@esbuild/aix-ppc64': 0.20.0 + '@esbuild/android-arm': 0.20.0 + '@esbuild/android-arm64': 0.20.0 + '@esbuild/android-x64': 0.20.0 + '@esbuild/darwin-arm64': 0.20.0 + '@esbuild/darwin-x64': 0.20.0 + '@esbuild/freebsd-arm64': 0.20.0 + '@esbuild/freebsd-x64': 0.20.0 + '@esbuild/linux-arm': 0.20.0 + '@esbuild/linux-arm64': 0.20.0 + '@esbuild/linux-ia32': 0.20.0 + '@esbuild/linux-loong64': 0.20.0 + '@esbuild/linux-mips64el': 0.20.0 + '@esbuild/linux-ppc64': 0.20.0 + '@esbuild/linux-riscv64': 0.20.0 + '@esbuild/linux-s390x': 0.20.0 + '@esbuild/linux-x64': 0.20.0 + '@esbuild/netbsd-x64': 0.20.0 + '@esbuild/openbsd-x64': 0.20.0 + '@esbuild/sunos-x64': 0.20.0 + '@esbuild/win32-arm64': 0.20.0 + '@esbuild/win32-ia32': 0.20.0 + '@esbuild/win32-x64': 0.20.0 dev: true /escalade@3.1.1: @@ -6995,19 +6982,19 @@ packages: optionalDependencies: source-map: 0.6.1 - /eslint-plugin-vue@9.22.0(eslint@8.57.0): - resolution: {integrity: sha512-7wCXv5zuVnBtZE/74z4yZ0CM8AjH6bk4MQGm7hZjUC2DBppKU5ioeOk5LGSg/s9a1ZJnIsdPLJpXnu1Rc+cVHg==} + /eslint-plugin-vue@9.20.1(eslint@8.56.0): + resolution: {integrity: sha512-GyCs8K3lkEvoyC1VV97GJhP1SvqsKCiWGHnbn0gVUYiUhaH2+nB+Dv1uekv1THFMPbBfYxukrzQdltw950k+LQ==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - eslint: 8.57.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + eslint: 8.56.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.0.15 semver: 7.6.0 - vue-eslint-parser: 9.4.2(eslint@8.57.0) + vue-eslint-parser: 9.4.2(eslint@8.56.0) xml-name-validator: 4.0.0 transitivePeerDependencies: - supports-color @@ -7025,15 +7012,15 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - /eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + /eslint@8.56.0: + resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@eslint-community/regexpp': 4.6.2 '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.0 + '@eslint/js': 8.56.0 '@humanwhocodes/config-array': 0.11.14 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -7367,7 +7354,7 @@ packages: dev: false patched: true - /floating-vue@5.2.2(vue@3.4.21): + /floating-vue@5.2.2(vue@3.4.19): resolution: {integrity: sha512-afW+h2CFafo+7Y9Lvw/xsqjaQlKLdJV7h1fCHfcYQ1C4SVMlu7OAekqWgu5d4SgvkBVU0pVpLlVsrSTBURFRkg==} peerDependencies: '@nuxt/kit': ^3.2.0 @@ -7377,8 +7364,8 @@ packages: optional: true dependencies: '@floating-ui/dom': 1.1.1 - vue: 3.4.21(typescript@5.3.3) - vue-resize: 2.0.0-alpha.1(vue@3.4.21) + vue: 3.4.19(typescript@5.3.3) + vue-resize: 2.0.0-alpha.1(vue@3.4.19) dev: false /follow-redirects@1.15.4(debug@4.3.4): @@ -7662,8 +7649,8 @@ packages: strip-bom-string: 1.0.0 dev: true - /happy-dom@13.6.2: - resolution: {integrity: sha512-Ku+wDqcF/KwFA0dI+xIMZd9Jn020RXjuSil/Vz7gu2yhDC3FsDYZ55qqV9k+SGC4opwb4acisXqVSRxUJMlPbQ==} + /happy-dom@13.3.5: + resolution: {integrity: sha512-PBMhFNNBPGVa8oDP7mHv+kTWNtzIPTogS+V05s3ddsluDmTbcU7EaEMxZdYf2ka55MshloE9/opOHEC+YelzVQ==} engines: {node: '>=16.0.0'} dependencies: entities: 4.5.0 @@ -7730,16 +7717,16 @@ packages: engines: {node: '>=12.0.0'} dev: false - /histoire@0.17.9(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0)(vite@5.1.4): + /histoire@0.17.9(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0)(vite@5.0.12): resolution: {integrity: sha512-z5Jb9QwbOw0TKvpkU0v7+CxJG6hIljIKMhWXzOfteteRZGDFElpTEwbr5/8EdPI6VTdF/k76fqZ07nmS9YdUvA==} hasBin: true peerDependencies: vite: ^2.9.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 dependencies: '@akryum/tinypool': 0.3.1 - '@histoire/app': 0.17.9(vite@5.1.4) - '@histoire/controls': 0.17.9(vite@5.1.4) - '@histoire/shared': 0.17.9(vite@5.1.4) + '@histoire/app': 0.17.9(vite@5.0.12) + '@histoire/controls': 0.17.9(vite@5.0.12) + '@histoire/shared': 0.17.9(vite@5.0.12) '@histoire/vendors': 0.17.8 '@types/flexsearch': 0.7.6 '@types/markdown-it': 12.2.3 @@ -7766,8 +7753,8 @@ packages: sade: 1.8.1 shiki-es: 0.2.0 sirv: 2.0.3 - vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) - vite-node: 0.34.6(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vite-node: 0.34.6(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) transitivePeerDependencies: - '@types/node' - bufferutil @@ -8213,7 +8200,7 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 20.11.22 + '@types/node': 20.11.10 merge-stream: 2.0.0 supports-color: 7.2.0 dev: true @@ -8248,10 +8235,6 @@ packages: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true - /js-tokens@8.0.3: - resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==} - dev: true - /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -9260,7 +9243,7 @@ packages: engines: {node: '>=0.10.0'} dev: true - /pinia@2.1.7(typescript@5.3.3)(vue@3.4.21): + /pinia@2.1.7(typescript@5.3.3)(vue@3.4.19): resolution: {integrity: sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==} peerDependencies: '@vue/composition-api': ^1.4.0 @@ -9274,8 +9257,8 @@ packages: dependencies: '@vue/devtools-api': 6.5.0 typescript: 5.3.3 - vue: 3.4.21(typescript@5.3.3) - vue-demi: 0.14.6(vue@3.4.21) + vue: 3.4.19(typescript@5.3.3) + vue-demi: 0.14.6(vue@3.4.19) dev: false /pkg-dir@4.2.0: @@ -9292,27 +9275,27 @@ packages: mlly: 1.4.2 pathe: 1.1.1 - /postcss-attribute-case-insensitive@6.0.3(postcss@8.4.35): + /postcss-attribute-case-insensitive@6.0.3(postcss@8.4.33): resolution: {integrity: sha512-KHkmCILThWBRtg+Jn1owTnHPnFit4OkqS+eKiGEOPIGke54DCeYGJ6r0Fx/HjfE9M9kznApCLcU0DvnPchazMQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 - postcss-selector-parser: 6.0.13 + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 dev: true - /postcss-clamp@4.1.0(postcss@8.4.35): + /postcss-clamp@4.1.0(postcss@8.4.33): resolution: {integrity: sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==} engines: {node: '>=7.6.0'} peerDependencies: postcss: ^8.4.6 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /postcss-color-functional-notation@6.0.5(postcss@8.4.35): + /postcss-color-functional-notation@6.0.5(postcss@8.4.33): resolution: {integrity: sha512-aTFsIy89ftjyclwUHRwvz1IxucLzVrzmmcXmtbPWT9GdyYeaJEKeAwbaZzOZn7AQlXg4xfwgkYhKsofC4aLIwg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -9321,34 +9304,34 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 dev: true - /postcss-color-hex-alpha@9.0.4(postcss@8.4.35): + /postcss-color-hex-alpha@9.0.4(postcss@8.4.33): resolution: {integrity: sha512-XQZm4q4fNFqVCYMGPiBjcqDhuG7Ey2xrl99AnDJMyr5eDASsAGalndVgHZF8i97VFNy1GQeZc4q2ydagGmhelQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /postcss-color-rebeccapurple@9.0.3(postcss@8.4.35): + /postcss-color-rebeccapurple@9.0.3(postcss@8.4.33): resolution: {integrity: sha512-ruBqzEFDYHrcVq3FnW3XHgwRqVMrtEPLBtD7K2YmsLKVc2jbkxzzNEctJKsPCpDZ+LeMHLKRDoSShVefGc+CkQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /postcss-custom-media@10.0.3(postcss@8.4.35): + /postcss-custom-media@10.0.3(postcss@8.4.33): resolution: {integrity: sha512-wfJ9nKpLn/Qy7LASKu0Rj9Iq2uMzlRt27P4FAE1889IKRMdYUgy8SqvdXfAOs7LJLQX9Fjm0mZ+TSFphD/mKwA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -9358,10 +9341,10 @@ packages: '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 '@csstools/media-query-list-parser': 2.1.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /postcss-custom-properties@13.3.5(postcss@8.4.35): + /postcss-custom-properties@13.3.5(postcss@8.4.33): resolution: {integrity: sha512-xHg8DTCMfN2nrqs2CQTF+0m5jgnzKL5zrW5Y05KF6xBRO0uDPxiplBm/xcr1o49SLbyJXkMuaRJKhRzkrquKnQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -9370,12 +9353,12 @@ packages: '@csstools/cascade-layer-name-parser': 1.0.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /postcss-custom-selectors@7.1.7(postcss@8.4.35): + /postcss-custom-selectors@7.1.7(postcss@8.4.33): resolution: {integrity: sha512-N19MpExaR+hYTXU59VO02xE42zLoAUYSVcupwkKlWWLteOb+sWCWHw5FhV7u7gVLTzaGULy7nZP3DNTHgOZAPA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -9384,29 +9367,29 @@ packages: '@csstools/cascade-layer-name-parser': 1.0.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - postcss: 8.4.35 - postcss-selector-parser: 6.0.13 + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 dev: true - /postcss-dir-pseudo-class@8.0.1(postcss@8.4.35): + /postcss-dir-pseudo-class@8.0.1(postcss@8.4.33): resolution: {integrity: sha512-uULohfWBBVoFiZXgsQA24JV6FdKIidQ+ZqxOouhWwdE+qJlALbkS5ScB43ZTjPK+xUZZhlaO/NjfCt5h4IKUfw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 - postcss-selector-parser: 6.0.13 + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 dev: true - /postcss-double-position-gradients@5.0.4(postcss@8.4.35): + /postcss-double-position-gradients@5.0.4(postcss@8.4.33): resolution: {integrity: sha512-xOH2QhazCPeYR+ziYaDcGlpo7Bpw8PVoggOFfU/xPkmBRUQH8MR2eWoPY1CZM93CB0WKs2mxq3ORo83QGIooLw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true @@ -9420,65 +9403,65 @@ packages: postcss-value-parser: 3.3.1 dev: true - /postcss-easings@4.0.0(postcss@8.4.35): + /postcss-easings@4.0.0(postcss@8.4.33): resolution: {integrity: sha512-KNpwHA3mTnf0UWcdwahQDaz7DDJ6QteVwdlLff98se854p6pyQW9iofwrD05vtlp33AAAxuUGCOhYwERRJGy6Q==} engines: {node: '>=16.0'} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /postcss-focus-visible@9.0.1(postcss@8.4.35): + /postcss-focus-visible@9.0.1(postcss@8.4.33): resolution: {integrity: sha512-N2VQ5uPz3Z9ZcqI5tmeholn4d+1H14fKXszpjogZIrFbhaq0zNAtq8sAnw6VLiqGbL8YBzsnu7K9bBkTqaRimQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 - postcss-selector-parser: 6.0.13 + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 dev: true - /postcss-focus-within@8.0.1(postcss@8.4.35): + /postcss-focus-within@8.0.1(postcss@8.4.33): resolution: {integrity: sha512-NFU3xcY/xwNaapVb+1uJ4n23XImoC86JNwkY/uduytSl2s9Ekc2EpzmRR63+ExitnW3Mab3Fba/wRPCT5oDILA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 postcss-selector-parser: 6.0.13 dev: true - /postcss-font-variant@5.0.0(postcss@8.4.35): + /postcss-font-variant@5.0.0(postcss@8.4.33): resolution: {integrity: sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /postcss-gap-properties@5.0.1(postcss@8.4.35): + /postcss-gap-properties@5.0.1(postcss@8.4.33): resolution: {integrity: sha512-k2z9Cnngc24c0KF4MtMuDdToROYqGMMUQGcE6V0odwjHyOHtaDBlLeRBV70y9/vF7KIbShrTRZ70JjsI1BZyWw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /postcss-image-set-function@6.0.3(postcss@8.4.35): + /postcss-image-set-function@6.0.3(postcss@8.4.33): resolution: {integrity: sha512-i2bXrBYzfbRzFnm+pVuxVePSTCRiNmlfssGI4H0tJQvDue+yywXwUxe68VyzXs7cGtMaH6MCLY6IbCShrSroCw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /postcss-lab-function@6.0.10(postcss@8.4.35): + /postcss-lab-function@6.0.10(postcss@8.4.33): resolution: {integrity: sha512-Csvw/CwwuwTojK2O3Ad0SvYKrfnAKy+uvT+1Fjk6igR+n8gHuJHIwdj1A2s46EZZojg3RkibdMBuv1vMvR6Sng==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -9487,164 +9470,164 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) - '@csstools/utilities': 1.0.0(postcss@8.4.35) - postcss: 8.4.35 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) + '@csstools/utilities': 1.0.0(postcss@8.4.33) + postcss: 8.4.33 dev: true - /postcss-logical@7.0.1(postcss@8.4.35): + /postcss-logical@7.0.1(postcss@8.4.33): resolution: {integrity: sha512-8GwUQZE0ri0K0HJHkDv87XOLC8DE0msc+HoWLeKdtjDZEwpZ5xuK3QdV6FhmHSQW40LPkg43QzvATRAI3LsRkg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /postcss-nesting@12.0.4(postcss@8.4.35): + /postcss-nesting@12.0.4(postcss@8.4.33): resolution: {integrity: sha512-WuCe0KnP4vKjLZK8VNoUWKL8ZLOv/5jiM94mHcI3VszLropHwmjotdUyP/ObzqZpXuQKP2Jf9R12vIHKFSStKw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.13) - postcss: 8.4.35 - postcss-selector-parser: 6.0.13 + '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.15) + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 dev: true - /postcss-opacity-percentage@2.0.0(postcss@8.4.35): + /postcss-opacity-percentage@2.0.0(postcss@8.4.33): resolution: {integrity: sha512-lyDrCOtntq5Y1JZpBFzIWm2wG9kbEdujpNt4NLannF+J9c8CgFIzPa80YQfdza+Y+yFfzbYj/rfoOsYsooUWTQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /postcss-overflow-shorthand@5.0.1(postcss@8.4.35): + /postcss-overflow-shorthand@5.0.1(postcss@8.4.33): resolution: {integrity: sha512-XzjBYKLd1t6vHsaokMV9URBt2EwC9a7nDhpQpjoPk2HRTSQfokPfyAS/Q7AOrzUu6q+vp/GnrDBGuj/FCaRqrQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /postcss-page-break@3.0.4(postcss@8.4.35): + /postcss-page-break@3.0.4(postcss@8.4.33): resolution: {integrity: sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==} peerDependencies: postcss: ^8 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /postcss-place@9.0.1(postcss@8.4.35): + /postcss-place@9.0.1(postcss@8.4.33): resolution: {integrity: sha512-JfL+paQOgRQRMoYFc2f73pGuG/Aw3tt4vYMR6UA3cWVMxivviPTnMFnFTczUJOA4K2Zga6xgQVE+PcLs64WC8Q==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 postcss-value-parser: 4.2.0 dev: true - /postcss-preset-env@9.4.0(postcss@8.4.35): - resolution: {integrity: sha512-5X2UA4Dn4xo7sJFCxlzW/dAGo71Oxh/K5DVls33hd2e3j06OKnW5FJQTw2hB0wTnGv0f6WcMaVBGFqcEfAgwlw==} + /postcss-preset-env@9.3.0(postcss@8.4.33): + resolution: {integrity: sha512-ycw6doPrqV6QxDCtgiyGDef61bEfiSc59HGM4gOw/wxQxmKnhuEery61oOC/5ViENz/ycpRsuhTexs1kUBTvVw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/postcss-cascade-layers': 4.0.3(postcss@8.4.35) - '@csstools/postcss-color-function': 3.0.10(postcss@8.4.35) - '@csstools/postcss-color-mix-function': 2.0.10(postcss@8.4.35) - '@csstools/postcss-exponential-functions': 1.0.4(postcss@8.4.35) - '@csstools/postcss-font-format-keywords': 3.0.2(postcss@8.4.35) - '@csstools/postcss-gamut-mapping': 1.0.3(postcss@8.4.35) - '@csstools/postcss-gradients-interpolation-method': 4.0.11(postcss@8.4.35) - '@csstools/postcss-hwb-function': 3.0.9(postcss@8.4.35) - '@csstools/postcss-ic-unit': 3.0.4(postcss@8.4.35) - '@csstools/postcss-initial': 1.0.1(postcss@8.4.35) - '@csstools/postcss-is-pseudo-class': 4.0.5(postcss@8.4.35) - '@csstools/postcss-light-dark-function': 1.0.0(postcss@8.4.35) - '@csstools/postcss-logical-float-and-clear': 2.0.1(postcss@8.4.35) - '@csstools/postcss-logical-overflow': 1.0.1(postcss@8.4.35) - '@csstools/postcss-logical-overscroll-behavior': 1.0.1(postcss@8.4.35) - '@csstools/postcss-logical-resize': 2.0.1(postcss@8.4.35) - '@csstools/postcss-logical-viewport-units': 2.0.6(postcss@8.4.35) - '@csstools/postcss-media-minmax': 1.1.3(postcss@8.4.35) - '@csstools/postcss-media-queries-aspect-ratio-number-values': 2.0.6(postcss@8.4.35) - '@csstools/postcss-nested-calc': 3.0.2(postcss@8.4.35) - '@csstools/postcss-normalize-display-values': 3.0.2(postcss@8.4.35) - '@csstools/postcss-oklab-function': 3.0.10(postcss@8.4.35) - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) - '@csstools/postcss-relative-color-syntax': 2.0.10(postcss@8.4.35) - '@csstools/postcss-scope-pseudo-class': 3.0.1(postcss@8.4.35) - '@csstools/postcss-stepped-value-functions': 3.0.5(postcss@8.4.35) - '@csstools/postcss-text-decoration-shorthand': 3.0.4(postcss@8.4.35) - '@csstools/postcss-trigonometric-functions': 3.0.5(postcss@8.4.35) - '@csstools/postcss-unset-value': 3.0.1(postcss@8.4.35) - autoprefixer: 10.4.17(postcss@8.4.35) - browserslist: 4.23.0 - css-blank-pseudo: 6.0.1(postcss@8.4.35) - css-has-pseudo: 6.0.2(postcss@8.4.35) - css-prefers-color-scheme: 9.0.1(postcss@8.4.35) + '@csstools/postcss-cascade-layers': 4.0.3(postcss@8.4.33) + '@csstools/postcss-color-function': 3.0.10(postcss@8.4.33) + '@csstools/postcss-color-mix-function': 2.0.10(postcss@8.4.33) + '@csstools/postcss-exponential-functions': 1.0.4(postcss@8.4.33) + '@csstools/postcss-font-format-keywords': 3.0.2(postcss@8.4.33) + '@csstools/postcss-gamut-mapping': 1.0.3(postcss@8.4.33) + '@csstools/postcss-gradients-interpolation-method': 4.0.11(postcss@8.4.33) + '@csstools/postcss-hwb-function': 3.0.9(postcss@8.4.33) + '@csstools/postcss-ic-unit': 3.0.4(postcss@8.4.33) + '@csstools/postcss-initial': 1.0.1(postcss@8.4.33) + '@csstools/postcss-is-pseudo-class': 4.0.5(postcss@8.4.33) + '@csstools/postcss-logical-float-and-clear': 2.0.1(postcss@8.4.33) + '@csstools/postcss-logical-overflow': 1.0.1(postcss@8.4.33) + '@csstools/postcss-logical-overscroll-behavior': 1.0.1(postcss@8.4.33) + '@csstools/postcss-logical-resize': 2.0.1(postcss@8.4.33) + '@csstools/postcss-logical-viewport-units': 2.0.6(postcss@8.4.33) + '@csstools/postcss-media-minmax': 1.1.3(postcss@8.4.33) + '@csstools/postcss-media-queries-aspect-ratio-number-values': 2.0.6(postcss@8.4.33) + '@csstools/postcss-nested-calc': 3.0.2(postcss@8.4.33) + '@csstools/postcss-normalize-display-values': 3.0.2(postcss@8.4.33) + '@csstools/postcss-oklab-function': 3.0.10(postcss@8.4.33) + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) + '@csstools/postcss-relative-color-syntax': 2.0.10(postcss@8.4.33) + '@csstools/postcss-scope-pseudo-class': 3.0.1(postcss@8.4.33) + '@csstools/postcss-stepped-value-functions': 3.0.5(postcss@8.4.33) + '@csstools/postcss-text-decoration-shorthand': 3.0.4(postcss@8.4.33) + '@csstools/postcss-trigonometric-functions': 3.0.5(postcss@8.4.33) + '@csstools/postcss-unset-value': 3.0.1(postcss@8.4.33) + autoprefixer: 10.4.17(postcss@8.4.33) + browserslist: 4.22.3 + css-blank-pseudo: 6.0.1(postcss@8.4.33) + css-has-pseudo: 6.0.1(postcss@8.4.33) + css-prefers-color-scheme: 9.0.1(postcss@8.4.33) cssdb: 7.11.1 - postcss: 8.4.35 - postcss-attribute-case-insensitive: 6.0.3(postcss@8.4.35) - postcss-clamp: 4.1.0(postcss@8.4.35) - postcss-color-functional-notation: 6.0.5(postcss@8.4.35) - postcss-color-hex-alpha: 9.0.4(postcss@8.4.35) - postcss-color-rebeccapurple: 9.0.3(postcss@8.4.35) - postcss-custom-media: 10.0.3(postcss@8.4.35) - postcss-custom-properties: 13.3.5(postcss@8.4.35) - postcss-custom-selectors: 7.1.7(postcss@8.4.35) - postcss-dir-pseudo-class: 8.0.1(postcss@8.4.35) - postcss-double-position-gradients: 5.0.4(postcss@8.4.35) - postcss-focus-visible: 9.0.1(postcss@8.4.35) - postcss-focus-within: 8.0.1(postcss@8.4.35) - postcss-font-variant: 5.0.0(postcss@8.4.35) - postcss-gap-properties: 5.0.1(postcss@8.4.35) - postcss-image-set-function: 6.0.3(postcss@8.4.35) - postcss-lab-function: 6.0.10(postcss@8.4.35) - postcss-logical: 7.0.1(postcss@8.4.35) - postcss-nesting: 12.0.4(postcss@8.4.35) - postcss-opacity-percentage: 2.0.0(postcss@8.4.35) - postcss-overflow-shorthand: 5.0.1(postcss@8.4.35) - postcss-page-break: 3.0.4(postcss@8.4.35) - postcss-place: 9.0.1(postcss@8.4.35) - postcss-pseudo-class-any-link: 9.0.1(postcss@8.4.35) - postcss-replace-overflow-wrap: 4.0.0(postcss@8.4.35) - postcss-selector-not: 7.0.2(postcss@8.4.35) + postcss: 8.4.33 + postcss-attribute-case-insensitive: 6.0.3(postcss@8.4.33) + postcss-clamp: 4.1.0(postcss@8.4.33) + postcss-color-functional-notation: 6.0.5(postcss@8.4.33) + postcss-color-hex-alpha: 9.0.4(postcss@8.4.33) + postcss-color-rebeccapurple: 9.0.3(postcss@8.4.33) + postcss-custom-media: 10.0.3(postcss@8.4.33) + postcss-custom-properties: 13.3.5(postcss@8.4.33) + postcss-custom-selectors: 7.1.7(postcss@8.4.33) + postcss-dir-pseudo-class: 8.0.1(postcss@8.4.33) + postcss-double-position-gradients: 5.0.4(postcss@8.4.33) + postcss-focus-visible: 9.0.1(postcss@8.4.33) + postcss-focus-within: 8.0.1(postcss@8.4.33) + postcss-font-variant: 5.0.0(postcss@8.4.33) + postcss-gap-properties: 5.0.1(postcss@8.4.33) + postcss-image-set-function: 6.0.3(postcss@8.4.33) + postcss-lab-function: 6.0.10(postcss@8.4.33) + postcss-logical: 7.0.1(postcss@8.4.33) + postcss-nesting: 12.0.4(postcss@8.4.33) + postcss-opacity-percentage: 2.0.0(postcss@8.4.33) + postcss-overflow-shorthand: 5.0.1(postcss@8.4.33) + postcss-page-break: 3.0.4(postcss@8.4.33) + postcss-place: 9.0.1(postcss@8.4.33) + postcss-pseudo-class-any-link: 9.0.1(postcss@8.4.33) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.4.33) + postcss-selector-not: 7.0.2(postcss@8.4.33) + postcss-value-parser: 4.2.0 dev: true - /postcss-pseudo-class-any-link@9.0.1(postcss@8.4.35): + /postcss-pseudo-class-any-link@9.0.1(postcss@8.4.33): resolution: {integrity: sha512-cKYGGZ9yzUZi+dZd7XT2M8iSDfo+T2Ctbpiizf89uBTBfIpZpjvTavzIJXpCReMVXSKROqzpxClNu6fz4DHM0Q==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 - postcss-selector-parser: 6.0.13 + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 dev: true - /postcss-replace-overflow-wrap@4.0.0(postcss@8.4.35): + /postcss-replace-overflow-wrap@4.0.0(postcss@8.4.33): resolution: {integrity: sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==} peerDependencies: postcss: ^8.0.3 dependencies: - postcss: 8.4.35 + postcss: 8.4.33 dev: true - /postcss-selector-not@7.0.2(postcss@8.4.35): + /postcss-selector-not@7.0.2(postcss@8.4.33): resolution: {integrity: sha512-/SSxf/90Obye49VZIfc0ls4H0P6i6V1iHv0pzZH8SdgvZOPFkF37ef1r5cyWcMflJSFJ5bfuoluTnFnBBFiuSA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.35 - postcss-selector-parser: 6.0.13 + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 dev: true /postcss-selector-parser@6.0.13: @@ -9679,8 +9662,8 @@ packages: source-map: 0.6.1 dev: true - /postcss@8.4.35: - resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} + /postcss@8.4.33: + resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.7 @@ -10174,7 +10157,7 @@ packages: - acorn dev: true - /rollup-plugin-visualizer@5.12.0(rollup@4.12.0): + /rollup-plugin-visualizer@5.12.0(rollup@4.9.6): resolution: {integrity: sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==} engines: {node: '>=14'} hasBin: true @@ -10186,7 +10169,7 @@ packages: dependencies: open: 8.4.0 picomatch: 2.3.1 - rollup: 4.12.0 + rollup: 4.9.6 source-map: 0.7.4 yargs: 17.6.0 dev: true @@ -10199,26 +10182,26 @@ packages: fsevents: 2.3.3 dev: true - /rollup@4.12.0: - resolution: {integrity: sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==} + /rollup@4.9.6: + resolution: {integrity: sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.12.0 - '@rollup/rollup-android-arm64': 4.12.0 - '@rollup/rollup-darwin-arm64': 4.12.0 - '@rollup/rollup-darwin-x64': 4.12.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.12.0 - '@rollup/rollup-linux-arm64-gnu': 4.12.0 - '@rollup/rollup-linux-arm64-musl': 4.12.0 - '@rollup/rollup-linux-riscv64-gnu': 4.12.0 - '@rollup/rollup-linux-x64-gnu': 4.12.0 - '@rollup/rollup-linux-x64-musl': 4.12.0 - '@rollup/rollup-win32-arm64-msvc': 4.12.0 - '@rollup/rollup-win32-ia32-msvc': 4.12.0 - '@rollup/rollup-win32-x64-msvc': 4.12.0 + '@rollup/rollup-android-arm-eabi': 4.9.6 + '@rollup/rollup-android-arm64': 4.9.6 + '@rollup/rollup-darwin-arm64': 4.9.6 + '@rollup/rollup-darwin-x64': 4.9.6 + '@rollup/rollup-linux-arm-gnueabihf': 4.9.6 + '@rollup/rollup-linux-arm64-gnu': 4.9.6 + '@rollup/rollup-linux-arm64-musl': 4.9.6 + '@rollup/rollup-linux-riscv64-gnu': 4.9.6 + '@rollup/rollup-linux-x64-gnu': 4.9.6 + '@rollup/rollup-linux-x64-musl': 4.9.6 + '@rollup/rollup-win32-arm64-msvc': 4.9.6 + '@rollup/rollup-win32-ia32-msvc': 4.9.6 + '@rollup/rollup-win32-x64-msvc': 4.9.6 fsevents: 2.3.3 /rope-sequence@1.3.4: @@ -10263,8 +10246,8 @@ packages: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} dev: true - /sass@1.71.1: - resolution: {integrity: sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==} + /sass@1.70.0: + resolution: {integrity: sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==} engines: {node: '>=14.0.0'} hasBin: true dependencies: @@ -10638,10 +10621,10 @@ packages: engines: {node: '>=8'} dev: true - /strip-literal@2.0.0: - resolution: {integrity: sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==} + /strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} dependencies: - js-tokens: 8.0.3 + acorn: 8.11.2 dev: true /style-mod@4.1.0: @@ -11059,13 +11042,13 @@ packages: engines: {node: '>=4'} dev: true - /update-browserslist-db@1.0.13(browserslist@4.23.0): + /update-browserslist-db@1.0.13(browserslist@4.22.3): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.23.0 + browserslist: 4.22.3 escalade: 3.1.1 picocolors: 1.0.0 dev: true @@ -11151,7 +11134,7 @@ packages: extsprintf: 1.3.0 dev: true - /vite-node@0.34.6(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0): + /vite-node@0.34.6(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0): resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} engines: {node: '>=v14.18.0'} hasBin: true @@ -11161,7 +11144,7 @@ packages: mlly: 1.4.2 pathe: 1.1.1 picocolors: 1.0.0 - vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) transitivePeerDependencies: - '@types/node' - less @@ -11173,8 +11156,8 @@ packages: - terser dev: true - /vite-node@1.3.1(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0): - resolution: {integrity: sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==} + /vite-node@1.2.2(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0): + resolution: {integrity: sha512-1as4rDTgVWJO3n1uHmUYqq7nsFgINQ9u+mRcXpjeOMJUmviqNKjcZB7UfRZrlM7MjYXMKpuWp5oGkjaFLnjawg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true dependencies: @@ -11182,7 +11165,7 @@ packages: debug: 4.3.4(supports-color@8.1.1) pathe: 1.1.1 picocolors: 1.0.0 - vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) transitivePeerDependencies: - '@types/node' - less @@ -11194,62 +11177,58 @@ packages: - terser dev: true - /vite-plugin-inject-preload@1.3.3(vite@5.1.4): + /vite-plugin-inject-preload@1.3.3(vite@5.0.12): resolution: {integrity: sha512-nh5+6BZdR/iFZj6pfDR8NHxQgRELkcmM5f9ufj9X6BWXgh3x6SWNp24TfiYvhwQyOV/vrVXpo0DqNBSgppmeOQ==} engines: {node: '>=14.18.0'} peerDependencies: vite: ^3.0.0 || ^4.0.0 dependencies: mime-types: 2.1.35 - vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) dev: true - /vite-plugin-pwa@0.19.1(vite@5.1.4)(workbox-build@7.0.0)(workbox-window@7.0.0): - resolution: {integrity: sha512-pxubJSqDfiUflmFfU8ErPP2eIHz7SqiSuJz6Qk2dPlEeC5Wm2hTInYhmVBYVx1KbVUEhQ4f8uCdmhYB/YP/pqw==} + /vite-plugin-pwa@0.17.5(vite@5.0.12)(workbox-build@7.0.0)(workbox-window@7.0.0): + resolution: {integrity: sha512-UxRNPiJBzh4tqU/vc8G2TxmrUTzT6BqvSzhszLk62uKsf+npXdvLxGDz9C675f4BJi6MbD2tPnJhi5txlMzxbQ==} engines: {node: '>=16.0.0'} peerDependencies: - '@vite-pwa/assets-generator': ^0.2.4 vite: ^3.1.0 || ^4.0.0 || ^5.0.0 workbox-build: ^7.0.0 workbox-window: ^7.0.0 - peerDependenciesMeta: - '@vite-pwa/assets-generator': - optional: true dependencies: debug: 4.3.4(supports-color@8.1.1) fast-glob: 3.3.2 pretty-bytes: 6.1.1 - vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) workbox-build: 7.0.0(acorn@8.11.2) workbox-window: 7.0.0 transitivePeerDependencies: - supports-color dev: true - /vite-plugin-sentry@1.4.0(vite@5.1.4): - resolution: {integrity: sha512-Jt9AeDnh9XLjEA1pAfU0NW0jCyJE8lAXMJWZKc+SoIxZRKSY64fitDOg9Ta1G98LhPaiDKL6dhVeROUmjY/aUQ==} + /vite-plugin-sentry@1.3.0(vite@5.0.12): + resolution: {integrity: sha512-cei2ocb0l9hOuij8//DPMFl2Fcl0gVOBWGbqZ7F3aNLHUFkZvGm+B+aTWPX9CDpwW0uLcqqoo8O9rckFF0PGLA==} engines: {node: '>= 14'} peerDependencies: - vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 dependencies: '@sentry/cli': 2.19.1 - vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) transitivePeerDependencies: - encoding - supports-color dev: true - /vite-svg-loader@5.1.0(vue@3.4.21): + /vite-svg-loader@5.1.0(vue@3.4.19): resolution: {integrity: sha512-M/wqwtOEjgb956/+m5ZrYT/Iq6Hax0OakWbokj8+9PXOnB7b/4AxESHieEtnNEy7ZpjsjYW1/5nK8fATQMmRxw==} peerDependencies: vue: '>=3.2.13' dependencies: svgo: 3.0.2 - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) dev: true - /vite@5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0): - resolution: {integrity: sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==} + /vite@5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0): + resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -11276,25 +11255,25 @@ packages: terser: optional: true dependencies: - '@types/node': 20.11.22 + '@types/node': 20.11.10 esbuild: 0.19.12 - postcss: 8.4.35 - rollup: 4.12.0 - sass: 1.71.1 + postcss: 8.4.33 + rollup: 4.9.6 + sass: 1.70.0 terser: 5.24.0 optionalDependencies: fsevents: 2.3.3 dev: true - /vitest@1.3.1(@types/node@20.11.22)(happy-dom@13.6.2)(sass@1.71.1)(terser@5.24.0): - resolution: {integrity: sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ==} + /vitest@1.2.2(@types/node@20.11.10)(happy-dom@13.3.5)(sass@1.70.0)(terser@5.24.0): + resolution: {integrity: sha512-d5Ouvrnms3GD9USIK36KG8OZ5bEvKEkITFtnGv56HFaSlbItJuYr7hv2Lkn903+AvRAgSixiamozUVfORUekjw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 1.3.1 - '@vitest/ui': 1.3.1 + '@vitest/browser': ^1.0.0 + '@vitest/ui': ^1.0.0 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -11311,27 +11290,28 @@ packages: jsdom: optional: true dependencies: - '@types/node': 20.11.22 - '@vitest/expect': 1.3.1 - '@vitest/runner': 1.3.1 - '@vitest/snapshot': 1.3.1 - '@vitest/spy': 1.3.1 - '@vitest/utils': 1.3.1 + '@types/node': 20.11.10 + '@vitest/expect': 1.2.2 + '@vitest/runner': 1.2.2 + '@vitest/snapshot': 1.2.2 + '@vitest/spy': 1.2.2 + '@vitest/utils': 1.2.2 acorn-walk: 8.3.2 + cac: 6.7.14 chai: 4.3.10 debug: 4.3.4(supports-color@8.1.1) execa: 8.0.1 - happy-dom: 13.6.2 + happy-dom: 13.3.5 local-pkg: 0.5.0 magic-string: 0.30.7 pathe: 1.1.1 picocolors: 1.0.0 std-env: 3.6.0 - strip-literal: 2.0.0 + strip-literal: 1.3.0 tinybench: 2.5.1 tinypool: 0.8.2 - vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) - vite-node: 1.3.1(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vite-node: 1.2.2(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -11343,7 +11323,7 @@ packages: - terser dev: true - /vue-advanced-cropper@2.8.8(vue@3.4.21): + /vue-advanced-cropper@2.8.8(vue@3.4.19): resolution: {integrity: sha512-yDM7Jb/gnxcs//JdbOogBUoHr1bhCQSto7/ohgETKAe4wvRpmqIkKSppMm1huVQr+GP1YoVlX/fkjKxvYzwwDQ==} engines: {node: '>=8', npm: '>=5'} peerDependencies: @@ -11352,14 +11332,14 @@ packages: classnames: 2.3.1 debounce: 1.2.1 easy-bem: 1.1.1 - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) dev: false /vue-component-type-helpers@1.8.22: resolution: {integrity: sha512-LK3wJHs3vJxHG292C8cnsRusgyC5SEZDCzDCD01mdE/AoREFMl2tzLRuzwyuEsOIz13tqgBcnvysN3Lxsa14Fw==} dev: true - /vue-demi@0.14.6(vue@3.4.21): + /vue-demi@0.14.6(vue@3.4.19): resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} engines: {node: '>=12'} hasBin: true @@ -11371,10 +11351,10 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) dev: false - /vue-demi@0.14.7(vue@3.4.21): + /vue-demi@0.14.7(vue@3.4.19): resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==} engines: {node: '>=12'} hasBin: true @@ -11386,35 +11366,17 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) dev: false - /vue-eslint-parser@9.3.1(eslint@8.57.0): + /vue-eslint-parser@9.3.1(eslint@8.56.0): resolution: {integrity: sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' dependencies: debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.4.2 - lodash: 4.17.21 - semver: 7.5.4 - transitivePeerDependencies: - - supports-color - dev: true - - /vue-eslint-parser@9.4.2(eslint@8.57.0): - resolution: {integrity: sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==} - engines: {node: ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '>=6.0.0' - dependencies: - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + eslint: 8.56.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 @@ -11425,17 +11387,35 @@ packages: - supports-color dev: true - /vue-flatpickr-component@11.0.4(vue@3.4.21): + /vue-eslint-parser@9.4.2(eslint@8.56.0): + resolution: {integrity: sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.56.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.4.2 + lodash: 4.17.21 + semver: 7.6.0 + transitivePeerDependencies: + - supports-color + dev: true + + /vue-flatpickr-component@11.0.4(vue@3.4.19): resolution: {integrity: sha512-rhYYCfKpPHMaqTYy/jUlzg2HOlmvSMtEUJ7uB5R1gZZfxyarE5h80WAO/vtbCxxgS030KcZywIQjZG4tIgW4xg==} engines: {node: '>=14.13.0'} peerDependencies: vue: ^3.2.0 dependencies: flatpickr: 4.6.13 - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) dev: false - /vue-i18n@9.9.1(vue@3.4.21): + /vue-i18n@9.9.1(vue@3.4.19): resolution: {integrity: sha512-xyQ4VspLdNSPTKBFBPWa1tvtj+9HuockZwgFeD2OhxxXuC2CWeNvV4seu2o9+vbQOyQbhAM5Ez56oxUrrnTWdw==} engines: {node: '>= 16'} peerDependencies: @@ -11444,24 +11424,24 @@ packages: '@intlify/core-base': 9.9.1 '@intlify/shared': 9.9.1 '@vue/devtools-api': 6.5.0 - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) dev: false - /vue-resize@2.0.0-alpha.1(vue@3.4.21): + /vue-resize@2.0.0-alpha.1(vue@3.4.19): resolution: {integrity: sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==} peerDependencies: vue: ^3.0.0 dependencies: - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) dev: false - /vue-router@4.3.0(vue@3.4.21): + /vue-router@4.3.0(vue@3.4.19): resolution: {integrity: sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ==} peerDependencies: vue: ^3.2.0 dependencies: '@vue/devtools-api': 6.6.1 - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) dev: false /vue-template-compiler@2.7.14: @@ -11483,19 +11463,19 @@ packages: typescript: 5.3.3 dev: true - /vue@3.4.21(typescript@5.3.3): - resolution: {integrity: sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==} + /vue@3.4.19(typescript@5.3.3): + resolution: {integrity: sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@vue/compiler-dom': 3.4.21 - '@vue/compiler-sfc': 3.4.21 - '@vue/runtime-dom': 3.4.21 - '@vue/server-renderer': 3.4.21(vue@3.4.21) - '@vue/shared': 3.4.21 + '@vue/compiler-dom': 3.4.19 + '@vue/compiler-sfc': 3.4.19 + '@vue/runtime-dom': 3.4.19 + '@vue/server-renderer': 3.4.19(vue@3.4.19) + '@vue/shared': 3.4.19 typescript: 5.3.3 /w3c-keyname@2.2.6: @@ -11935,13 +11915,13 @@ packages: engines: {node: '>=12.20'} dev: true - /zhyswan-vuedraggable@4.1.3(vue@3.4.21): + /zhyswan-vuedraggable@4.1.3(vue@3.4.19): resolution: {integrity: sha512-q4Mp52tQIvTAWG0CKxLCVLyG/3RnIskDxoJvfjDZ2kM8yTcMkY80VTc8rd3q9KwqJ0UVtjEGLufb23sjDp0peQ==} peerDependencies: vue: ^3.0.1 dependencies: sortablejs: 1.14.0 - vue: 3.4.21(typescript@5.3.3) + vue: 3.4.19(typescript@5.3.3) dev: false /zod@3.22.4: -- 2.45.1 From 45bff868ab87f4725417307202c4f7cc71f8a303 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 2 Mar 2024 09:23:42 +0100 Subject: [PATCH 90/93] docs: add scope mapping to provider --- docs/content/doc/setup/openid.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/content/doc/setup/openid.md b/docs/content/doc/setup/openid.md index 21d9e58f4..aa1b655d3 100644 --- a/docs/content/doc/setup/openid.md +++ b/docs/content/doc/setup/openid.md @@ -53,6 +53,8 @@ output example: } ``` +5. In Authentik's menu on the left, go to Applications > Providers > Select the Vikunja provider. Then click on "Edit", on the bottom open "Advanced protocol settings", select the newly created property mapping under "Scopes". Save the provider. + Now when you log into Vikunja via Authentik it will show you a list of scopes you are claiming. You should see the description you entered on the oidc provider's admin area. -- 2.45.1 From 4d887710def46eed4ca833041eee48c82786067e Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 2 Mar 2024 09:24:12 +0100 Subject: [PATCH 91/93] docs: remove duplicates --- docs/content/doc/usage/errors.md | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/docs/content/doc/usage/errors.md b/docs/content/doc/usage/errors.md index 4c257a966..1ff2ea801 100644 --- a/docs/content/doc/usage/errors.md +++ b/docs/content/doc/usage/errors.md @@ -111,21 +111,6 @@ This document describes the different errors Vikunja can return. | 6009 | 400 | There is no oidc team with that team name and oidcId. | | 6010 | 400 | There are no oidc teams found for the user. | - -| ErrorCode | HTTP Status Code | Description | -|-----------|------------------|-------------| -| 6001 | 400 | The team name cannot be emtpy. | -| 6002 | 404 | The team does not exist. | -| 6004 | 409 | The team already has access to that namespace or list. | -| 6005 | 409 | The user is already a member of that team. | -| 6006 | 400 | Cannot delete the last team member. | -| 6007 | 403 | The team does not have access to the list to perform that action. | -| 6008 | 400 | There are no teams found with that team name. | -| 6009 | 400 | There is no oidc team with that team name and oidcId. | -| 6010 | 400 | There are no oidc teams found for the user. | - - - ## User Project Access | ErrorCode | HTTP Status Code | Description | -- 2.45.1 From f99459f92958267fe785fd689a9afdc1e4e85ced Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 2 Mar 2024 09:25:45 +0100 Subject: [PATCH 92/93] docs: add link to Keycloak mapper --- docs/content/doc/setup/openid.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/content/doc/setup/openid.md b/docs/content/doc/setup/openid.md index aa1b655d3..12121930a 100644 --- a/docs/content/doc/setup/openid.md +++ b/docs/content/doc/setup/openid.md @@ -61,6 +61,10 @@ You should see the description you entered on the oidc provider's admin area. Proceed to vikunja and open the teams page in the sidebar menu. You should see "(sso: *your_oidcID*)" written next to each team you were assigned through oidc. +## Setup in Keycloak + +The kind people from the Darmstadt Makerspace have written [a guide on how to create a mapper for Vikunja here](https://github.com/makerspace-darmstadt/keycloak-vikunja-mapper). + ## Use cases All examples assume one team called "Team 1" in your provider. -- 2.45.1 From d7b580154968f3863e3c7347b49749daec148745 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 2 Mar 2024 09:30:20 +0100 Subject: [PATCH 93/93] chore: reset pnpm lock --- frontend/pnpm-lock.yaml | 1964 ++++++++++++++++++++------------------- 1 file changed, 992 insertions(+), 972 deletions(-) diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index f9e11e871..967c879a7 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -21,124 +21,124 @@ dependencies: version: 6.5.1 '@fortawesome/vue-fontawesome': specifier: 3.0.6 - version: 3.0.6(@fortawesome/fontawesome-svg-core@6.5.1)(vue@3.4.19) + version: 3.0.6(@fortawesome/fontawesome-svg-core@6.5.1)(vue@3.4.21) '@github/hotkey': specifier: 3.1.0 version: 3.1.0 '@infectoone/vue-ganttastic': specifier: 2.2.0 - version: 2.2.0(dayjs@1.11.10)(vue@3.4.19) + version: 2.2.0(dayjs@1.11.10)(vue@3.4.21) '@intlify/unplugin-vue-i18n': specifier: 2.0.0 - version: 2.0.0(rollup@4.9.6)(vue-i18n@9.9.1) + version: 2.0.0(rollup@4.12.0)(vue-i18n@9.9.1) '@kyvg/vue3-notification': specifier: 3.2.0 - version: 3.2.0(vue@3.4.19) + version: 3.2.0(vue@3.4.21) '@sentry/tracing': - specifier: 7.102.0 - version: 7.102.0 + specifier: 7.103.0 + version: 7.103.0 '@sentry/vue': - specifier: 7.102.0 - version: 7.102.0(vue@3.4.19) + specifier: 7.103.0 + version: 7.103.0(vue@3.4.21) '@tiptap/core': - specifier: 2.2.3 - version: 2.2.3(@tiptap/pm@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/pm@2.2.4) '@tiptap/extension-blockquote': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-bold': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-bullet-list': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-code': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-code-block-lowlight': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/extension-code-block@2.1.12)(@tiptap/pm@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/extension-code-block@2.1.12)(@tiptap/pm@2.2.4) '@tiptap/extension-document': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-dropcursor': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) '@tiptap/extension-gapcursor': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) '@tiptap/extension-hard-break': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-heading': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-history': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) '@tiptap/extension-horizontal-rule': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) '@tiptap/extension-image': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-italic': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-link': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) '@tiptap/extension-list-item': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-ordered-list': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-paragraph': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-placeholder': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) '@tiptap/extension-strike': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-table': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) '@tiptap/extension-table-cell': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-table-header': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-table-row': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-task-item': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) '@tiptap/extension-task-list': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-text': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-typography': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/extension-underline': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4) '@tiptap/pm': - specifier: 2.2.3 - version: 2.2.3 + specifier: 2.2.4 + version: 2.2.4 '@tiptap/suggestion': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) '@tiptap/vue-3': - specifier: 2.2.3 - version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3)(vue@3.4.19) + specifier: 2.2.4 + version: 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4)(vue@3.4.21) '@types/is-touch-device': specifier: 1.0.2 version: 1.0.2 @@ -146,11 +146,11 @@ dependencies: specifier: 4.5.9 version: 4.5.9 '@vueuse/core': - specifier: 10.8.0 - version: 10.8.0(vue@3.4.19) + specifier: 10.9.0 + version: 10.9.0(vue@3.4.21) '@vueuse/router': - specifier: 10.8.0 - version: 10.8.0(vue-router@4.3.0)(vue@3.4.19) + specifier: 10.9.0 + version: 10.9.0(vue-router@4.3.0)(vue@3.4.21) axios: specifier: 1.6.7 version: 1.6.7(debug@4.3.4) @@ -183,7 +183,7 @@ dependencies: version: 0.7.31(patch_hash=bfn3sngfuhktmdj7jgl3ejl35y) floating-vue: specifier: 5.2.2 - version: 5.2.2(vue@3.4.19) + version: 5.2.2(vue@3.4.21) is-touch-device: specifier: 1.0.1 version: 1.0.1 @@ -198,7 +198,7 @@ dependencies: version: 2.9.0 pinia: specifier: 2.1.7 - version: 2.1.7(typescript@5.3.3)(vue@3.4.19) + version: 2.1.7(typescript@5.3.3)(vue@3.4.21) register-service-worker: specifier: 1.7.2 version: 1.7.2 @@ -215,46 +215,46 @@ dependencies: specifier: 1.4.0 version: 1.4.0 vue: - specifier: 3.4.19 - version: 3.4.19(typescript@5.3.3) + specifier: 3.4.21 + version: 3.4.21(typescript@5.3.3) vue-advanced-cropper: specifier: 2.8.8 - version: 2.8.8(vue@3.4.19) + version: 2.8.8(vue@3.4.21) vue-flatpickr-component: specifier: 11.0.4 - version: 11.0.4(vue@3.4.19) + version: 11.0.4(vue@3.4.21) vue-i18n: specifier: 9.9.1 - version: 9.9.1(vue@3.4.19) + version: 9.9.1(vue@3.4.21) vue-router: specifier: 4.3.0 - version: 4.3.0(vue@3.4.19) + version: 4.3.0(vue@3.4.21) workbox-precaching: specifier: 7.0.0 version: 7.0.0 zhyswan-vuedraggable: specifier: 4.1.3 - version: 4.1.3(vue@3.4.19) + version: 4.1.3(vue@3.4.21) devDependencies: '@4tw/cypress-drag-drop': specifier: 2.2.5 - version: 2.2.5(cypress@13.6.3) + version: 2.2.5(cypress@13.6.6) '@cypress/vite-dev-server': specifier: 5.0.7 version: 5.0.7 '@cypress/vue': specifier: 6.0.0 - version: 6.0.0(cypress@13.6.3)(vue@3.4.19) + version: 6.0.0(cypress@13.6.6)(vue@3.4.21) '@faker-js/faker': - specifier: 8.4.0 - version: 8.4.0 + specifier: 8.4.1 + version: 8.4.1 '@histoire/plugin-screenshot': specifier: 0.17.8 version: 0.17.8(histoire@0.17.9) '@histoire/plugin-vue': - specifier: 0.17.9 - version: 0.17.9(histoire@0.17.9)(vite@5.0.12)(vue@3.4.19) + specifier: 0.17.12 + version: 0.17.12(histoire@0.17.9)(vite@5.1.4)(vue@3.4.21) '@rushstack/eslint-patch': specifier: 1.7.2 version: 1.7.2 @@ -277,92 +277,92 @@ devDependencies: specifier: 5.0.2 version: 5.0.2 '@types/node': - specifier: 20.11.10 - version: 20.11.10 + specifier: 20.11.22 + version: 20.11.22 '@types/postcss-preset-env': specifier: 7.7.0 version: 7.7.0 '@types/sortablejs': - specifier: 1.15.7 - version: 1.15.7 + specifier: 1.15.8 + version: 1.15.8 '@typescript-eslint/eslint-plugin': - specifier: 7.0.1 - version: 7.0.1(@typescript-eslint/parser@7.0.1)(eslint@8.56.0)(typescript@5.3.3) + specifier: 7.1.0 + version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3) '@typescript-eslint/parser': - specifier: 7.0.1 - version: 7.0.1(eslint@8.56.0)(typescript@5.3.3) + specifier: 7.1.0 + version: 7.1.0(eslint@8.57.0)(typescript@5.3.3) '@vitejs/plugin-legacy': - specifier: 5.3.0 - version: 5.3.0(esbuild@0.20.0)(terser@5.24.0)(vite@5.0.12) + specifier: 5.3.1 + version: 5.3.1(esbuild@0.20.1)(terser@5.24.0)(vite@5.1.4) '@vitejs/plugin-vue': - specifier: 5.0.3 - version: 5.0.3(vite@5.0.12)(vue@3.4.19) + specifier: 5.0.4 + version: 5.0.4(vite@5.1.4)(vue@3.4.21) '@vue/eslint-config-typescript': specifier: 12.0.0 - version: 12.0.0(eslint-plugin-vue@9.20.1)(eslint@8.56.0)(typescript@5.3.3) + version: 12.0.0(eslint-plugin-vue@9.22.0)(eslint@8.57.0)(typescript@5.3.3) '@vue/test-utils': specifier: 2.4.4 - version: 2.4.4(vue@3.4.19) + version: 2.4.4(vue@3.4.21) '@vue/tsconfig': specifier: 0.5.1 version: 0.5.1 autoprefixer: specifier: 10.4.17 - version: 10.4.17(postcss@8.4.33) + version: 10.4.17(postcss@8.4.35) browserslist: - specifier: 4.22.3 - version: 4.22.3 + specifier: 4.23.0 + version: 4.23.0 caniuse-lite: - specifier: 1.0.30001581 - version: 1.0.30001581 + specifier: 1.0.30001591 + version: 1.0.30001591 css-has-pseudo: - specifier: 6.0.1 - version: 6.0.1(postcss@8.4.33) + specifier: 6.0.2 + version: 6.0.2(postcss@8.4.35) csstype: specifier: 3.1.3 version: 3.1.3 cypress: - specifier: 13.6.3 - version: 13.6.3 + specifier: 13.6.6 + version: 13.6.6 esbuild: - specifier: 0.20.0 - version: 0.20.0 + specifier: 0.20.1 + version: 0.20.1 eslint: - specifier: 8.56.0 - version: 8.56.0 + specifier: 8.57.0 + version: 8.57.0 eslint-plugin-vue: - specifier: 9.20.1 - version: 9.20.1(eslint@8.56.0) + specifier: 9.22.0 + version: 9.22.0(eslint@8.57.0) happy-dom: - specifier: 13.3.5 - version: 13.3.5 + specifier: 13.6.2 + version: 13.6.2 histoire: specifier: 0.17.9 - version: 0.17.9(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0)(vite@5.0.12) + version: 0.17.9(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0)(vite@5.1.4) postcss: - specifier: 8.4.33 - version: 8.4.33 + specifier: 8.4.35 + version: 8.4.35 postcss-easing-gradients: specifier: 3.0.1 version: 3.0.1 postcss-easings: specifier: 4.0.0 - version: 4.0.0(postcss@8.4.33) + version: 4.0.0(postcss@8.4.35) postcss-focus-within: specifier: 8.0.1 - version: 8.0.1(postcss@8.4.33) + version: 8.0.1(postcss@8.4.35) postcss-preset-env: - specifier: 9.3.0 - version: 9.3.0(postcss@8.4.33) + specifier: 9.4.0 + version: 9.4.0(postcss@8.4.35) rollup: - specifier: 4.9.6 - version: 4.9.6 + specifier: 4.12.0 + version: 4.12.0 rollup-plugin-visualizer: specifier: 5.12.0 - version: 5.12.0(rollup@4.9.6) + version: 5.12.0(rollup@4.12.0) sass: - specifier: 1.70.0 - version: 1.70.0 + specifier: 1.71.1 + version: 1.71.1 start-server-and-test: specifier: 2.0.3 version: 2.0.3 @@ -370,23 +370,23 @@ devDependencies: specifier: 5.3.3 version: 5.3.3 vite: - specifier: 5.0.12 - version: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + specifier: 5.1.4 + version: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) vite-plugin-inject-preload: specifier: 1.3.3 - version: 1.3.3(vite@5.0.12) + version: 1.3.3(vite@5.1.4) vite-plugin-pwa: - specifier: 0.17.5 - version: 0.17.5(vite@5.0.12)(workbox-build@7.0.0)(workbox-window@7.0.0) + specifier: 0.19.1 + version: 0.19.1(vite@5.1.4)(workbox-build@7.0.0)(workbox-window@7.0.0) vite-plugin-sentry: - specifier: 1.3.0 - version: 1.3.0(vite@5.0.12) + specifier: 1.4.0 + version: 1.4.0(vite@5.1.4) vite-svg-loader: specifier: 5.1.0 - version: 5.1.0(vue@3.4.19) + version: 5.1.0(vue@3.4.21) vitest: - specifier: 1.2.2 - version: 1.2.2(@types/node@20.11.10)(happy-dom@13.3.5)(sass@1.70.0)(terser@5.24.0) + specifier: 1.3.1 + version: 1.3.1(@types/node@20.11.22)(happy-dom@13.6.2)(sass@1.71.1)(terser@5.24.0) vue-tsc: specifier: 1.8.27 version: 1.8.27(typescript@5.3.3) @@ -399,12 +399,12 @@ devDependencies: packages: - /@4tw/cypress-drag-drop@2.2.5(cypress@13.6.3): + /@4tw/cypress-drag-drop@2.2.5(cypress@13.6.6): resolution: {integrity: sha512-3ghTmzhOmUqeN6U3QmUnKRUxI7OMLbJA4hHUY/eS/FhWJgxbiGgcaELbolWnBAOpajPXcsNQGYEj9brd59WH6A==} peerDependencies: cypress: 2 - 13 dependencies: - cypress: 13.6.3 + cypress: 13.6.6 dev: true /@aashutoshrathi/word-wrap@1.2.6: @@ -526,7 +526,7 @@ packages: dependencies: '@babel/compat-data': 7.23.5 '@babel/helper-validator-option': 7.23.5 - browserslist: 4.22.3 + browserslist: 4.23.0 lru-cache: 5.1.1 semver: 6.3.1 dev: true @@ -2719,18 +2719,18 @@ packages: '@csstools/css-tokenizer': 2.2.3 dev: true - /@csstools/postcss-cascade-layers@4.0.3(postcss@8.4.33): + /@csstools/postcss-cascade-layers@4.0.3(postcss@8.4.35): resolution: {integrity: sha512-RbkQoOH23yGhWVetgBTwFgIOHEyU2tKMN7blTz/YAKKabR6tr9pP7mYS23Q9snFY2hr8WSaV8Le64KdM9BtUSA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.15) - postcss: 8.4.33 - postcss-selector-parser: 6.0.15 + '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.13) + postcss: 8.4.35 + postcss-selector-parser: 6.0.13 dev: true - /@csstools/postcss-color-function@3.0.10(postcss@8.4.33): + /@csstools/postcss-color-function@3.0.10(postcss@8.4.35): resolution: {integrity: sha512-jxiXmSl4ZYX8KewFjL5ef6of9uW73VkaHeDb2tqb5q4ZDPYxjusNX1KJ8UXY8+7ydqS5QBo42tVMrSMGy+rDmw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2739,12 +2739,12 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 dev: true - /@csstools/postcss-color-mix-function@2.0.10(postcss@8.4.33): + /@csstools/postcss-color-mix-function@2.0.10(postcss@8.4.35): resolution: {integrity: sha512-zeD856+FDCUjB077pPS+Z9OnTQnqpiJrao3TW+sasCb/gJ3vZCX7sRSRFsRUo0/MntTtJu9hkKv9eMkFmfjydA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2753,12 +2753,12 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 dev: true - /@csstools/postcss-exponential-functions@1.0.4(postcss@8.4.33): + /@csstools/postcss-exponential-functions@1.0.4(postcss@8.4.35): resolution: {integrity: sha512-frMf0CFVnZoGEKAHlxLy3s4g/tpjyFn5+A+h895UJNm9Uc+ewGT7+EeK7Kh9IHH4pD4FkaGW1vOQtER00PLurQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2767,21 +2767,21 @@ packages: '@csstools/css-calc': 1.1.7(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /@csstools/postcss-font-format-keywords@3.0.2(postcss@8.4.33): + /@csstools/postcss-font-format-keywords@3.0.2(postcss@8.4.35): resolution: {integrity: sha512-E0xz2sjm4AMCkXLCFvI/lyl4XO6aN1NCSMMVEOngFDJ+k2rDwfr6NDjWljk1li42jiLNChVX+YFnmfGCigZKXw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-gamut-mapping@1.0.3(postcss@8.4.33): + /@csstools/postcss-gamut-mapping@1.0.3(postcss@8.4.35): resolution: {integrity: sha512-P0+ude1KyCy9LXOe2pHJmpcXK4q/OQbr2Sn2wQSssMw0rALGmny2MfHiCqEu8n6mf2cN6lWDZdzY8enBk8WHXQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2790,10 +2790,10 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /@csstools/postcss-gradients-interpolation-method@4.0.11(postcss@8.4.33): + /@csstools/postcss-gradients-interpolation-method@4.0.11(postcss@8.4.35): resolution: {integrity: sha512-LFom5jCVUfzF+iuiOZvhvX7RRN8vc+tKpcKo9s4keEBAU2mPwV5/Fgz5iylEfXP/DZbEdq2C0At20urMi/lupw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2802,12 +2802,12 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 dev: true - /@csstools/postcss-hwb-function@3.0.9(postcss@8.4.33): + /@csstools/postcss-hwb-function@3.0.9(postcss@8.4.35): resolution: {integrity: sha512-S3/Z+mGHWIKAex7DLsHFDiku5lBEK34avT2My6sGPNCXB38TZjrKI0rd7JdN9oulem5sn+CU7oONyIftui24oQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2816,92 +2816,105 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 dev: true - /@csstools/postcss-ic-unit@3.0.4(postcss@8.4.33): + /@csstools/postcss-ic-unit@3.0.4(postcss@8.4.35): resolution: {integrity: sha512-OB6ojl33/TQHhjVx1NI+n3EnYbdUM6Q/mSUv3WFATdcz7IrH/CmBaZt7P1R6j1Xdp58thIa6jm4Je7saGs+2AA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-initial@1.0.1(postcss@8.4.33): + /@csstools/postcss-initial@1.0.1(postcss@8.4.35): resolution: {integrity: sha512-wtb+IbUIrIf8CrN6MLQuFR7nlU5C7PwuebfeEXfjthUha1+XZj2RVi+5k/lukToA24sZkYAiSJfHM8uG/UZIdg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /@csstools/postcss-is-pseudo-class@4.0.5(postcss@8.4.33): + /@csstools/postcss-is-pseudo-class@4.0.5(postcss@8.4.35): resolution: {integrity: sha512-qG3MI7IN3KY9UwdaE9E7G7sFydscVW7nAj5OGwaBP9tQPEEVdxXTGI+l1ZW5EUpZFSj+u3q/22fH5+8HI72+Bg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.15) - postcss: 8.4.33 - postcss-selector-parser: 6.0.15 + '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.13) + postcss: 8.4.35 + postcss-selector-parser: 6.0.13 dev: true - /@csstools/postcss-logical-float-and-clear@2.0.1(postcss@8.4.33): + /@csstools/postcss-light-dark-function@1.0.0(postcss@8.4.35): + resolution: {integrity: sha512-KHo633V16DGo6tmpr1ARAwO73CPBNmDI3PfSQYe7ZBMiv60WEizbcEroK75fHjxKYJ4tj9uCCzp5sYG4cEUqqw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) + '@csstools/css-tokenizer': 2.2.3 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 + dev: true + + /@csstools/postcss-logical-float-and-clear@2.0.1(postcss@8.4.35): resolution: {integrity: sha512-SsrWUNaXKr+e/Uo4R/uIsqJYt3DaggIh/jyZdhy/q8fECoJSKsSMr7nObSLdvoULB69Zb6Bs+sefEIoMG/YfOA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /@csstools/postcss-logical-overflow@1.0.1(postcss@8.4.33): + /@csstools/postcss-logical-overflow@1.0.1(postcss@8.4.35): resolution: {integrity: sha512-Kl4lAbMg0iyztEzDhZuQw8Sj9r2uqFDcU1IPl+AAt2nue8K/f1i7ElvKtXkjhIAmKiy5h2EY8Gt/Cqg0pYFDCw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /@csstools/postcss-logical-overscroll-behavior@1.0.1(postcss@8.4.33): + /@csstools/postcss-logical-overscroll-behavior@1.0.1(postcss@8.4.35): resolution: {integrity: sha512-+kHamNxAnX8ojPCtV8WPcUP3XcqMFBSDuBuvT6MHgq7oX4IQxLIXKx64t7g9LiuJzE7vd06Q9qUYR6bh4YnGpQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /@csstools/postcss-logical-resize@2.0.1(postcss@8.4.33): + /@csstools/postcss-logical-resize@2.0.1(postcss@8.4.35): resolution: {integrity: sha512-W5Gtwz7oIuFcKa5SmBjQ2uxr8ZoL7M2bkoIf0T1WeNqljMkBrfw1DDA8/J83k57NQ1kcweJEjkJ04pUkmyee3A==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-logical-viewport-units@2.0.6(postcss@8.4.33): + /@csstools/postcss-logical-viewport-units@2.0.6(postcss@8.4.35): resolution: {integrity: sha512-6hV0ngZh8J7HqNY3kyt+z5ABN/XE18qvrU7ne4YSkKfltrWDnQgGiW/Q+h7bdQz8/W5juAefcdCCAJUIBE7erg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: '@csstools/css-tokenizer': 2.2.3 - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 dev: true - /@csstools/postcss-media-minmax@1.1.3(postcss@8.4.33): + /@csstools/postcss-media-minmax@1.1.3(postcss@8.4.35): resolution: {integrity: sha512-W9AFRQSLvT+Dxtp20AewzGTUxzkJ21XSKzqRALwQdAv0uJGXkR76qgdhkoX0L/tcV4gXtgDfVtGYL/x2Nz/M5Q==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2911,10 +2924,10 @@ packages: '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 '@csstools/media-query-list-parser': 2.1.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /@csstools/postcss-media-queries-aspect-ratio-number-values@2.0.6(postcss@8.4.33): + /@csstools/postcss-media-queries-aspect-ratio-number-values@2.0.6(postcss@8.4.35): resolution: {integrity: sha512-awc2qenSDvx6r+w6G9xxENp+LsbvHC8mMMV23KYmk4pR3YL8JxeKPDSiDhmqd93FQ9nNNDc/CaCQEcvP+GV4rw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2923,31 +2936,31 @@ packages: '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 '@csstools/media-query-list-parser': 2.1.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /@csstools/postcss-nested-calc@3.0.2(postcss@8.4.33): + /@csstools/postcss-nested-calc@3.0.2(postcss@8.4.35): resolution: {integrity: sha512-ySUmPyawiHSmBW/VI44+IObcKH0v88LqFe0d09Sb3w4B1qjkaROc6d5IA3ll9kjD46IIX/dbO5bwFN/swyoyZA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-normalize-display-values@3.0.2(postcss@8.4.33): + /@csstools/postcss-normalize-display-values@3.0.2(postcss@8.4.35): resolution: {integrity: sha512-fCapyyT/dUdyPtrelQSIV+d5HqtTgnNP/BEG9IuhgXHt93Wc4CfC1bQ55GzKAjWrZbgakMQ7MLfCXEf3rlZJOw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-oklab-function@3.0.10(postcss@8.4.33): + /@csstools/postcss-oklab-function@3.0.10(postcss@8.4.35): resolution: {integrity: sha512-s9trs1c+gUMtaTtwrrIpdVQkUbRuwi6bQ9rBHaqwt4kd3kEnEYfP85uLY1inFx6Rt8OM2XVg3PSYbfnFSAO51A==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2956,22 +2969,22 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 dev: true - /@csstools/postcss-progressive-custom-properties@3.1.0(postcss@8.4.33): + /@csstools/postcss-progressive-custom-properties@3.1.0(postcss@8.4.35): resolution: {integrity: sha512-Mfb1T1BHa6pktLI+poMEHI7Q+VYvAsdwJZPFsSkIB2ZUsawCiPxXLw06BKSVPITxFlaY/FEUzfpyOTfX9YCE2w==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-relative-color-syntax@2.0.10(postcss@8.4.33): + /@csstools/postcss-relative-color-syntax@2.0.10(postcss@8.4.35): resolution: {integrity: sha512-IkTIk9Eq2VegSN4lgsljGY8boyfX3l3Pw58e+R9oyPe/Ye7r3NwuiQ3w0nkXoQ+RC+d240V6n7eZme2mEPqQvg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -2980,22 +2993,22 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 dev: true - /@csstools/postcss-scope-pseudo-class@3.0.1(postcss@8.4.33): + /@csstools/postcss-scope-pseudo-class@3.0.1(postcss@8.4.35): resolution: {integrity: sha512-3ZFonK2gfgqg29gUJ2w7xVw2wFJ1eNWVDONjbzGkm73gJHVCYK5fnCqlLr+N+KbEfv2XbWAO0AaOJCFB6Fer6A==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 - postcss-selector-parser: 6.0.15 + postcss: 8.4.35 + postcss-selector-parser: 6.0.13 dev: true - /@csstools/postcss-stepped-value-functions@3.0.5(postcss@8.4.33): + /@csstools/postcss-stepped-value-functions@3.0.5(postcss@8.4.35): resolution: {integrity: sha512-B8K8RaTrYVZLxbNzVUvFO3SlCDJDaUTAO7KRth05fa7f01ufPvb6ztdBuxSoRwOtmNp8iROxPJHOemWo2kBBtA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -3004,21 +3017,21 @@ packages: '@csstools/css-calc': 1.1.7(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /@csstools/postcss-text-decoration-shorthand@3.0.4(postcss@8.4.33): + /@csstools/postcss-text-decoration-shorthand@3.0.4(postcss@8.4.35): resolution: {integrity: sha512-yUZmbnUemgQmja7SpOZeU45+P49wNEgQguRdyTktFkZsHf7Gof+ZIYfvF6Cm+LsU1PwSupy4yUeEKKjX5+k6cQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: '@csstools/color-helpers': 4.0.0 - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /@csstools/postcss-trigonometric-functions@3.0.5(postcss@8.4.33): + /@csstools/postcss-trigonometric-functions@3.0.5(postcss@8.4.35): resolution: {integrity: sha512-RhBfQ0TsBudyPuoo8pXKdfQuUiQxMU/Sc5GyV57bWk93JbUHXq6b4CdPx+B/tHUeFKvocVJn/e2jbu96rh0d3Q==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -3027,34 +3040,34 @@ packages: '@csstools/css-calc': 1.1.7(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /@csstools/postcss-unset-value@3.0.1(postcss@8.4.33): + /@csstools/postcss-unset-value@3.0.1(postcss@8.4.35): resolution: {integrity: sha512-dbDnZ2ja2U8mbPP0Hvmt2RMEGBiF1H7oY6HYSpjteXJGihYwgxgTr6KRbbJ/V6c+4wd51M+9980qG4gKVn5ttg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /@csstools/selector-specificity@3.0.2(postcss-selector-parser@6.0.15): + /@csstools/selector-specificity@3.0.2(postcss-selector-parser@6.0.13): resolution: {integrity: sha512-RpHaZ1h9LE7aALeQXmXrJkRG84ZxIsctEN2biEUmFyKpzFM3zZ35eUMcIzZFsw/2olQE6v69+esEqU2f1MKycg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss-selector-parser: ^6.0.13 dependencies: - postcss-selector-parser: 6.0.15 + postcss-selector-parser: 6.0.13 dev: true - /@csstools/utilities@1.0.0(postcss@8.4.33): + /@csstools/utilities@1.0.0(postcss@8.4.35): resolution: {integrity: sha512-tAgvZQe/t2mlvpNosA4+CkMiZ2azISW5WPAcdSalZlEjQvUfghHxfQcrCiK/7/CrfAWVxyM88kGFYO82heIGDg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true /@cypress/request@3.0.1: @@ -3092,7 +3105,7 @@ packages: - supports-color dev: true - /@cypress/vue@6.0.0(cypress@13.6.3)(vue@3.4.19): + /@cypress/vue@6.0.0(cypress@13.6.6)(vue@3.4.21): resolution: {integrity: sha512-KMfRw8y/kXn/RJqaDdFnYnW7YLk47313UE3Yip+sLDjILJ2kA0WEiEa6MYKe58v8TNRtwcRpUH5xAYVNs1N6/A==} engines: {node: '>=8'} peerDependencies: @@ -3103,8 +3116,8 @@ packages: '@cypress/webpack-dev-server': optional: true dependencies: - cypress: 13.6.3 - vue: 3.4.19(typescript@5.3.3) + cypress: 13.6.6 + vue: 3.4.21(typescript@5.3.3) dev: true /@cypress/xvfb@1.2.4(supports-color@8.1.1): @@ -3125,8 +3138,8 @@ packages: dev: true optional: true - /@esbuild/aix-ppc64@0.20.0: - resolution: {integrity: sha512-fGFDEctNh0CcSwsiRPxiaqX0P5rq+AqE0SRhYGZ4PX46Lg1FNR6oCxJghf8YgY0WQEgQuh3lErUFE4KxLeRmmw==} + /@esbuild/aix-ppc64@0.20.1: + resolution: {integrity: sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA==} engines: {node: '>=12'} cpu: [ppc64] os: [aix] @@ -3143,8 +3156,8 @@ packages: dev: true optional: true - /@esbuild/android-arm64@0.20.0: - resolution: {integrity: sha512-aVpnM4lURNkp0D3qPoAzSG92VXStYmoVPOgXveAUoQBWRSuQzt51yvSju29J6AHPmwY1BjH49uR29oyfH1ra8Q==} + /@esbuild/android-arm64@0.20.1: + resolution: {integrity: sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -3161,8 +3174,8 @@ packages: dev: true optional: true - /@esbuild/android-arm@0.20.0: - resolution: {integrity: sha512-3bMAfInvByLHfJwYPJRlpTeaQA75n8C/QKpEaiS4HrFWFiJlNI0vzq/zCjBrhAYcPyVPG7Eo9dMrcQXuqmNk5g==} + /@esbuild/android-arm@0.20.1: + resolution: {integrity: sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -3179,8 +3192,8 @@ packages: dev: true optional: true - /@esbuild/android-x64@0.20.0: - resolution: {integrity: sha512-uK7wAnlRvjkCPzh8jJ+QejFyrP8ObKuR5cBIsQZ+qbMunwR8sbd8krmMbxTLSrDhiPZaJYKQAU5Y3iMDcZPhyQ==} + /@esbuild/android-x64@0.20.1: + resolution: {integrity: sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -3197,8 +3210,8 @@ packages: dev: true optional: true - /@esbuild/darwin-arm64@0.20.0: - resolution: {integrity: sha512-AjEcivGAlPs3UAcJedMa9qYg9eSfU6FnGHJjT8s346HSKkrcWlYezGE8VaO2xKfvvlZkgAhyvl06OJOxiMgOYQ==} + /@esbuild/darwin-arm64@0.20.1: + resolution: {integrity: sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -3215,8 +3228,8 @@ packages: dev: true optional: true - /@esbuild/darwin-x64@0.20.0: - resolution: {integrity: sha512-bsgTPoyYDnPv8ER0HqnJggXK6RyFy4PH4rtsId0V7Efa90u2+EifxytE9pZnsDgExgkARy24WUQGv9irVbTvIw==} + /@esbuild/darwin-x64@0.20.1: + resolution: {integrity: sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -3233,8 +3246,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64@0.20.0: - resolution: {integrity: sha512-kQ7jYdlKS335mpGbMW5tEe3IrQFIok9r84EM3PXB8qBFJPSc6dpWfrtsC/y1pyrz82xfUIn5ZrnSHQQsd6jebQ==} + /@esbuild/freebsd-arm64@0.20.1: + resolution: {integrity: sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -3251,8 +3264,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-x64@0.20.0: - resolution: {integrity: sha512-uG8B0WSepMRsBNVXAQcHf9+Ko/Tr+XqmK7Ptel9HVmnykupXdS4J7ovSQUIi0tQGIndhbqWLaIL/qO/cWhXKyQ==} + /@esbuild/freebsd-x64@0.20.1: + resolution: {integrity: sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -3269,8 +3282,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm64@0.20.0: - resolution: {integrity: sha512-uTtyYAP5veqi2z9b6Gr0NUoNv9F/rOzI8tOD5jKcCvRUn7T60Bb+42NDBCWNhMjkQzI0qqwXkQGo1SY41G52nw==} + /@esbuild/linux-arm64@0.20.1: + resolution: {integrity: sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -3287,8 +3300,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm@0.20.0: - resolution: {integrity: sha512-2ezuhdiZw8vuHf1HKSf4TIk80naTbP9At7sOqZmdVwvvMyuoDiZB49YZKLsLOfKIr77+I40dWpHVeY5JHpIEIg==} + /@esbuild/linux-arm@0.20.1: + resolution: {integrity: sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -3305,8 +3318,8 @@ packages: dev: true optional: true - /@esbuild/linux-ia32@0.20.0: - resolution: {integrity: sha512-c88wwtfs8tTffPaoJ+SQn3y+lKtgTzyjkD8NgsyCtCmtoIC8RDL7PrJU05an/e9VuAke6eJqGkoMhJK1RY6z4w==} + /@esbuild/linux-ia32@0.20.1: + resolution: {integrity: sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -3323,8 +3336,8 @@ packages: dev: true optional: true - /@esbuild/linux-loong64@0.20.0: - resolution: {integrity: sha512-lR2rr/128/6svngnVta6JN4gxSXle/yZEZL3o4XZ6esOqhyR4wsKyfu6qXAL04S4S5CgGfG+GYZnjFd4YiG3Aw==} + /@esbuild/linux-loong64@0.20.1: + resolution: {integrity: sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -3341,8 +3354,8 @@ packages: dev: true optional: true - /@esbuild/linux-mips64el@0.20.0: - resolution: {integrity: sha512-9Sycc+1uUsDnJCelDf6ZNqgZQoK1mJvFtqf2MUz4ujTxGhvCWw+4chYfDLPepMEvVL9PDwn6HrXad5yOrNzIsQ==} + /@esbuild/linux-mips64el@0.20.1: + resolution: {integrity: sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -3359,8 +3372,8 @@ packages: dev: true optional: true - /@esbuild/linux-ppc64@0.20.0: - resolution: {integrity: sha512-CoWSaaAXOZd+CjbUTdXIJE/t7Oz+4g90A3VBCHLbfuc5yUQU/nFDLOzQsN0cdxgXd97lYW/psIIBdjzQIwTBGw==} + /@esbuild/linux-ppc64@0.20.1: + resolution: {integrity: sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -3377,8 +3390,8 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64@0.20.0: - resolution: {integrity: sha512-mlb1hg/eYRJUpv8h/x+4ShgoNLL8wgZ64SUr26KwglTYnwAWjkhR2GpoKftDbPOCnodA9t4Y/b68H4J9XmmPzA==} + /@esbuild/linux-riscv64@0.20.1: + resolution: {integrity: sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -3395,8 +3408,8 @@ packages: dev: true optional: true - /@esbuild/linux-s390x@0.20.0: - resolution: {integrity: sha512-fgf9ubb53xSnOBqyvWEY6ukBNRl1mVX1srPNu06B6mNsNK20JfH6xV6jECzrQ69/VMiTLvHMicQR/PgTOgqJUQ==} + /@esbuild/linux-s390x@0.20.1: + resolution: {integrity: sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -3413,8 +3426,8 @@ packages: dev: true optional: true - /@esbuild/linux-x64@0.20.0: - resolution: {integrity: sha512-H9Eu6MGse++204XZcYsse1yFHmRXEWgadk2N58O/xd50P9EvFMLJTQLg+lB4E1cF2xhLZU5luSWtGTb0l9UeSg==} + /@esbuild/linux-x64@0.20.1: + resolution: {integrity: sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -3431,8 +3444,8 @@ packages: dev: true optional: true - /@esbuild/netbsd-x64@0.20.0: - resolution: {integrity: sha512-lCT675rTN1v8Fo+RGrE5KjSnfY0x9Og4RN7t7lVrN3vMSjy34/+3na0q7RIfWDAj0e0rCh0OL+P88lu3Rt21MQ==} + /@esbuild/netbsd-x64@0.20.1: + resolution: {integrity: sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -3449,8 +3462,8 @@ packages: dev: true optional: true - /@esbuild/openbsd-x64@0.20.0: - resolution: {integrity: sha512-HKoUGXz/TOVXKQ+67NhxyHv+aDSZf44QpWLa3I1lLvAwGq8x1k0T+e2HHSRvxWhfJrFxaaqre1+YyzQ99KixoA==} + /@esbuild/openbsd-x64@0.20.1: + resolution: {integrity: sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -3467,8 +3480,8 @@ packages: dev: true optional: true - /@esbuild/sunos-x64@0.20.0: - resolution: {integrity: sha512-GDwAqgHQm1mVoPppGsoq4WJwT3vhnz/2N62CzhvApFD1eJyTroob30FPpOZabN+FgCjhG+AgcZyOPIkR8dfD7g==} + /@esbuild/sunos-x64@0.20.1: + resolution: {integrity: sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -3485,8 +3498,8 @@ packages: dev: true optional: true - /@esbuild/win32-arm64@0.20.0: - resolution: {integrity: sha512-0vYsP8aC4TvMlOQYozoksiaxjlvUcQrac+muDqj1Fxy6jh9l9CZJzj7zmh8JGfiV49cYLTorFLxg7593pGldwQ==} + /@esbuild/win32-arm64@0.20.1: + resolution: {integrity: sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -3503,8 +3516,8 @@ packages: dev: true optional: true - /@esbuild/win32-ia32@0.20.0: - resolution: {integrity: sha512-p98u4rIgfh4gdpV00IqknBD5pC84LCub+4a3MO+zjqvU5MVXOc3hqR2UgT2jI2nh3h8s9EQxmOsVI3tyzv1iFg==} + /@esbuild/win32-ia32@0.20.1: + resolution: {integrity: sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -3521,8 +3534,8 @@ packages: dev: true optional: true - /@esbuild/win32-x64@0.20.0: - resolution: {integrity: sha512-NgJnesu1RtWihtTtXGFMU5YSE6JyyHPMxCwBZK7a6/8d31GuSo9l0Ss7w1Jw5QnKUawG6UEehs883kcXf5fYwg==} + /@esbuild/win32-x64@0.20.1: + resolution: {integrity: sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -3530,13 +3543,13 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.56.0 + eslint: 8.57.0 eslint-visitor-keys: 3.4.3 dev: true @@ -3562,13 +3575,13 @@ packages: - supports-color dev: true - /@eslint/js@8.56.0: - resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} + /@eslint/js@8.57.0: + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@faker-js/faker@8.4.0: - resolution: {integrity: sha512-htW87352wzUCdX1jyUQocUcmAaFqcR/w082EC8iP/gtkF0K+aKcBp0hR5Arb7dzR8tQ1TrhE9DNa5EbJELm84w==} + /@faker-js/faker@8.4.1: + resolution: {integrity: sha512-XQ3cU+Q8Uqmrbf2e0cIC/QN43sTBSC8KF12u29Mb47tWrt2hAgBXSgpZMj4Ao8Uk0iJcU99QsOCaIL8934obCg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13'} dev: true @@ -3612,14 +3625,14 @@ packages: '@fortawesome/fontawesome-common-types': 6.5.1 dev: false - /@fortawesome/vue-fontawesome@3.0.6(@fortawesome/fontawesome-svg-core@6.5.1)(vue@3.4.19): + /@fortawesome/vue-fontawesome@3.0.6(@fortawesome/fontawesome-svg-core@6.5.1)(vue@3.4.21): resolution: {integrity: sha512-akrL7lTroyNpPkoHtvK2UpsMzJr6jXdHaQ0YdcwqDsB8jdwlpNHZYijpOUd9KJsARr+VB3WXY4EyObepqJ4ytQ==} peerDependencies: '@fortawesome/fontawesome-svg-core': ~1 || ~6 vue: '>= 3.0.0 < 4' dependencies: '@fortawesome/fontawesome-svg-core': 6.5.1 - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) dev: false /@github/hotkey@3.1.0: @@ -3636,11 +3649,11 @@ packages: '@hapi/hoek': 9.2.1 dev: true - /@histoire/app@0.17.9(vite@5.0.12): + /@histoire/app@0.17.9(vite@5.1.4): resolution: {integrity: sha512-JoSGbsoo1/JY5TtTiMBUSPllIEJLvC6jHIGruvwPG/cJ3niqa3EyEMOsOWtcu+xjtx1uETgL9Yj5RJMJjC+OBA==} dependencies: - '@histoire/controls': 0.17.9(vite@5.0.12) - '@histoire/shared': 0.17.9(vite@5.0.12) + '@histoire/controls': 0.17.9(vite@5.1.4) + '@histoire/shared': 0.17.9(vite@5.1.4) '@histoire/vendors': 0.17.8 '@types/flexsearch': 0.7.6 flexsearch: 0.7.21 @@ -3649,7 +3662,7 @@ packages: - vite dev: true - /@histoire/controls@0.17.9(vite@5.0.12): + /@histoire/controls@0.17.9(vite@5.1.4): resolution: {integrity: sha512-1f1cE1NZ2emzGMRnGfAb/gCKDtBT3bUZzj3aAcDmhm3MA2Vy5tGYSb9j+KuTTj7+exhOrKefmedr9a0q1/5g2w==} dependencies: '@codemirror/commands': 6.3.2 @@ -3659,7 +3672,7 @@ packages: '@codemirror/state': 6.3.2 '@codemirror/theme-one-dark': 6.1.2 '@codemirror/view': 6.22.1 - '@histoire/shared': 0.17.9(vite@5.0.12) + '@histoire/shared': 0.17.9(vite@5.1.4) '@histoire/vendors': 0.17.8 transitivePeerDependencies: - vite @@ -3673,7 +3686,7 @@ packages: capture-website: 2.4.1 defu: 6.1.3 fs-extra: 10.1.0 - histoire: 0.17.9(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0)(vite@5.0.12) + histoire: 0.17.9(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0)(vite@5.1.4) pathe: 1.1.1 transitivePeerDependencies: - bufferutil @@ -3682,26 +3695,26 @@ packages: - utf-8-validate dev: true - /@histoire/plugin-vue@0.17.9(histoire@0.17.9)(vite@5.0.12)(vue@3.4.19): - resolution: {integrity: sha512-iN/DEx7CSmYg9ho35zYB5laXuQ5kgBjG/5FH6hskI24hBhWzrUbPU9fynXBpBHwlAxX6r1mn2ngOVN1OW79CBw==} + /@histoire/plugin-vue@0.17.12(histoire@0.17.9)(vite@5.1.4)(vue@3.4.21): + resolution: {integrity: sha512-mpx2uwHq/qemnX+ARQtDR3M9kIt1y4kBCmzBkOquhJTp61mtHMu4hZKSzzQpQWA2QxEyuuwpaNiU7Mlms13EaQ==} peerDependencies: histoire: ^0.17.9 vue: ^3.2.47 dependencies: - '@histoire/controls': 0.17.9(vite@5.0.12) - '@histoire/shared': 0.17.10(vite@5.0.12) + '@histoire/controls': 0.17.9(vite@5.1.4) + '@histoire/shared': 0.17.10(vite@5.1.4) '@histoire/vendors': 0.17.8 change-case: 4.1.2 globby: 13.2.2 - histoire: 0.17.9(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0)(vite@5.0.12) + histoire: 0.17.9(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0)(vite@5.1.4) launch-editor: 2.6.1 pathe: 1.1.1 - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) transitivePeerDependencies: - vite dev: true - /@histoire/shared@0.17.10(vite@5.0.12): + /@histoire/shared@0.17.10(vite@5.1.4): resolution: {integrity: sha512-8hzk/WKASrYfaJ+UtR6Mv7aZlP8IZvQ5POoHAi+JvHMJTtzCXZeuL0qdQAXg0zdk3vWIH20oSl6N8hZE1AP7yA==} peerDependencies: vite: ^2.9.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 @@ -3712,10 +3725,10 @@ packages: chokidar: 3.5.3 pathe: 1.1.1 picocolors: 1.0.0 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) dev: true - /@histoire/shared@0.17.9(vite@5.0.12): + /@histoire/shared@0.17.9(vite@5.1.4): resolution: {integrity: sha512-E/l4EzYc69/bOImUnvfi7h4/DHGl1rc96lkuMYulL5hjRjuNhSy5AlN5bG0nkVOG4RVIAnLGevMaMi207wtvLw==} peerDependencies: vite: ^2.9.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 @@ -3726,7 +3739,7 @@ packages: chokidar: 3.5.3 pathe: 1.1.1 picocolors: 1.0.0 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) dev: true /@histoire/vendors@0.17.8: @@ -3753,15 +3766,15 @@ packages: resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} dev: true - /@infectoone/vue-ganttastic@2.2.0(dayjs@1.11.10)(vue@3.4.19): + /@infectoone/vue-ganttastic@2.2.0(dayjs@1.11.10)(vue@3.4.21): resolution: {integrity: sha512-XvYGHP8FOPBavNR/ujuIAP2BYU2yrL+l9Xjn10VQeZfwdAvmh7aKXoAu+ONsnE2mBCA6h9r0AsLjfv/LYtW/tQ==} peerDependencies: dayjs: ^1.11.5 vue: ^3.2.40 dependencies: - '@vueuse/core': 9.13.0(vue@3.4.19) + '@vueuse/core': 9.13.0(vue@3.4.21) dayjs: 1.11.10 - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) transitivePeerDependencies: - '@vue/composition-api' dev: false @@ -3787,7 +3800,7 @@ packages: magic-string: 0.30.7 mlly: 1.4.2 source-map-js: 1.0.2 - vue-i18n: 9.9.1(vue@3.4.19) + vue-i18n: 9.9.1(vue@3.4.21) yaml-eslint-parser: 1.2.2 dev: false @@ -3830,7 +3843,7 @@ packages: engines: {node: '>= 16'} dev: false - /@intlify/unplugin-vue-i18n@2.0.0(rollup@4.9.6)(vue-i18n@9.9.1): + /@intlify/unplugin-vue-i18n@2.0.0(rollup@4.12.0)(vue-i18n@9.9.1): resolution: {integrity: sha512-1oKvm92L9l2od2H9wKx2ZvR4tzn7gUtd7bPLI7AWUmm7U9H1iEypndt5d985ypxGsEs0gToDaKTrytbBIJwwSg==} engines: {node: '>= 14.16'} peerDependencies: @@ -3847,7 +3860,7 @@ packages: dependencies: '@intlify/bundle-utils': 7.4.0(vue-i18n@9.9.1) '@intlify/shared': 9.8.0 - '@rollup/pluginutils': 5.0.2(rollup@4.9.6) + '@rollup/pluginutils': 5.0.2(rollup@4.12.0) '@vue/compiler-sfc': 3.3.13 debug: 4.3.4(supports-color@8.1.1) fast-glob: 3.3.2 @@ -3857,7 +3870,7 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 unplugin: 1.1.0 - vue-i18n: 9.9.1(vue@3.4.19) + vue-i18n: 9.9.1(vue@3.4.21) transitivePeerDependencies: - rollup - supports-color @@ -3914,12 +3927,12 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /@kyvg/vue3-notification@3.2.0(vue@3.4.19): + /@kyvg/vue3-notification@3.2.0(vue@3.4.21): resolution: {integrity: sha512-DKicfzxS6n7oMCkFoUqzb26Orjv8Oo3fhOgSDYM2I1mGDwBW+Tyb/yr2eauho0R+E5chNswZ3AUyAE9DqutXmg==} peerDependencies: vue: ^3.0.0 dependencies: - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) dev: false /@lezer/common@1.1.1: @@ -4086,7 +4099,7 @@ packages: rollup: 2.79.1 dev: true - /@rollup/pluginutils@5.0.2(rollup@4.9.6): + /@rollup/pluginutils@5.0.2(rollup@4.12.0): resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -4098,95 +4111,95 @@ packages: '@types/estree': 1.0.0 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 4.9.6 + rollup: 4.12.0 dev: false - /@rollup/rollup-android-arm-eabi@4.9.6: - resolution: {integrity: sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==} + /@rollup/rollup-android-arm-eabi@4.12.0: + resolution: {integrity: sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==} cpu: [arm] os: [android] requiresBuild: true optional: true - /@rollup/rollup-android-arm64@4.9.6: - resolution: {integrity: sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==} + /@rollup/rollup-android-arm64@4.12.0: + resolution: {integrity: sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==} cpu: [arm64] os: [android] requiresBuild: true optional: true - /@rollup/rollup-darwin-arm64@4.9.6: - resolution: {integrity: sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==} + /@rollup/rollup-darwin-arm64@4.12.0: + resolution: {integrity: sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==} cpu: [arm64] os: [darwin] requiresBuild: true optional: true - /@rollup/rollup-darwin-x64@4.9.6: - resolution: {integrity: sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==} + /@rollup/rollup-darwin-x64@4.12.0: + resolution: {integrity: sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==} cpu: [x64] os: [darwin] requiresBuild: true optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.9.6: - resolution: {integrity: sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==} + /@rollup/rollup-linux-arm-gnueabihf@4.12.0: + resolution: {integrity: sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==} cpu: [arm] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-arm64-gnu@4.9.6: - resolution: {integrity: sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==} + /@rollup/rollup-linux-arm64-gnu@4.12.0: + resolution: {integrity: sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-arm64-musl@4.9.6: - resolution: {integrity: sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==} + /@rollup/rollup-linux-arm64-musl@4.12.0: + resolution: {integrity: sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-riscv64-gnu@4.9.6: - resolution: {integrity: sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==} + /@rollup/rollup-linux-riscv64-gnu@4.12.0: + resolution: {integrity: sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==} cpu: [riscv64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-x64-gnu@4.9.6: - resolution: {integrity: sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==} + /@rollup/rollup-linux-x64-gnu@4.12.0: + resolution: {integrity: sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-x64-musl@4.9.6: - resolution: {integrity: sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==} + /@rollup/rollup-linux-x64-musl@4.12.0: + resolution: {integrity: sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-win32-arm64-msvc@4.9.6: - resolution: {integrity: sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==} + /@rollup/rollup-win32-arm64-msvc@4.12.0: + resolution: {integrity: sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==} cpu: [arm64] os: [win32] requiresBuild: true optional: true - /@rollup/rollup-win32-ia32-msvc@4.9.6: - resolution: {integrity: sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==} + /@rollup/rollup-win32-ia32-msvc@4.12.0: + resolution: {integrity: sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==} cpu: [ia32] os: [win32] requiresBuild: true optional: true - /@rollup/rollup-win32-x64-msvc@4.9.6: - resolution: {integrity: sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==} + /@rollup/rollup-win32-x64-msvc@4.12.0: + resolution: {integrity: sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==} cpu: [x64] os: [win32] requiresBuild: true @@ -4196,45 +4209,45 @@ packages: resolution: {integrity: sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==} dev: true - /@sentry-internal/feedback@7.102.0: - resolution: {integrity: sha512-GxHdzbOF4tg6TtyQzFqb/8c/p07n68qZC5KYwzs7AuW5ey0IPmdC58pOh3Kk52JA0P69/RZy39+r1p1Swr6C+Q==} + /@sentry-internal/feedback@7.103.0: + resolution: {integrity: sha512-2nYoCfP7FpiUR+xxO5y5BL2ajHrhM4fL7HSup6QKNn7gI7vLyllYOOuYFNHhSmsXCD0i00U8DBClGLcn+6DQqw==} engines: {node: '>=12'} dependencies: - '@sentry/core': 7.102.0 - '@sentry/types': 7.102.0 - '@sentry/utils': 7.102.0 + '@sentry/core': 7.103.0 + '@sentry/types': 7.103.0 + '@sentry/utils': 7.103.0 dev: false - /@sentry-internal/replay-canvas@7.102.0: - resolution: {integrity: sha512-rgNO4PdFv0AYflBsCNbSIwpQuOOJQTqyu8i8U0PupjveNjkm0CUJhber/ZOcaGmbyjdvwikGwgWY2O0Oj0USCA==} + /@sentry-internal/replay-canvas@7.103.0: + resolution: {integrity: sha512-EyDRMdlSqtwY8zGFhOWwl+nwwo98hlhJz+bpF5PQ6VmFpbplh6Wqfx2p+cPXQr40TGMMC4+vPFlSWTOMjcO9zQ==} engines: {node: '>=12'} dependencies: - '@sentry/core': 7.102.0 - '@sentry/replay': 7.102.0 - '@sentry/types': 7.102.0 - '@sentry/utils': 7.102.0 + '@sentry/core': 7.103.0 + '@sentry/replay': 7.103.0 + '@sentry/types': 7.103.0 + '@sentry/utils': 7.103.0 dev: false - /@sentry-internal/tracing@7.102.0: - resolution: {integrity: sha512-BlE33HWL1IzkGa0W+pwTiyu01MUIfYf+WnO9UC8qkDW3jxVvg2zhoSjXSxikT+KPCOgoZpQHspaTzwjnI1LCvw==} + /@sentry-internal/tracing@7.103.0: + resolution: {integrity: sha512-sZ/Wao8HOvGaBs7WlOdflMpHGAFkOBWL6hBiirHaOy5d+IDm7n7et5U6zhvcfiyYBO4nY36gy1Tg5mw+aNO0Vw==} engines: {node: '>=8'} dependencies: - '@sentry/core': 7.102.0 - '@sentry/types': 7.102.0 - '@sentry/utils': 7.102.0 + '@sentry/core': 7.103.0 + '@sentry/types': 7.103.0 + '@sentry/utils': 7.103.0 dev: false - /@sentry/browser@7.102.0: - resolution: {integrity: sha512-hIggcMnojIbWhbmlRfkykHmy6n7pjug0AHfF19HRUQxAx9KJfMH5YdWvohov0Hb9fS+jdvqgE+/4AWbEeXQrHw==} + /@sentry/browser@7.103.0: + resolution: {integrity: sha512-lP3Oplnwo1lY8ltk8SWzQURbxnSfVhYA099mVs1T95sdwXS16Za6SX7Ld/9T506ZW/WyoU4VCq7eKtG2kPFhMQ==} engines: {node: '>=8'} dependencies: - '@sentry-internal/feedback': 7.102.0 - '@sentry-internal/replay-canvas': 7.102.0 - '@sentry-internal/tracing': 7.102.0 - '@sentry/core': 7.102.0 - '@sentry/replay': 7.102.0 - '@sentry/types': 7.102.0 - '@sentry/utils': 7.102.0 + '@sentry-internal/feedback': 7.103.0 + '@sentry-internal/replay-canvas': 7.103.0 + '@sentry-internal/tracing': 7.103.0 + '@sentry/core': 7.103.0 + '@sentry/replay': 7.103.0 + '@sentry/types': 7.103.0 + '@sentry/utils': 7.103.0 dev: false /@sentry/cli@2.19.1: @@ -4253,54 +4266,54 @@ packages: - supports-color dev: true - /@sentry/core@7.102.0: - resolution: {integrity: sha512-GO9eLOSBK1waW4AD0wDXAreaNqXFQ1MPQZrkKcN+GJYEFhJK1+u+MSV7vO5Fs/rIfaTZIZ2jtEkxSSAOucE8EQ==} + /@sentry/core@7.103.0: + resolution: {integrity: sha512-LCI+PIDoF/RLqN41fNXum3ilmS6ukni6L7t38vSdibbe2G0804EbPLtOIpv2PkS8E6CFuRW5zOb+8OwEAAtZWw==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.102.0 - '@sentry/utils': 7.102.0 + '@sentry/types': 7.103.0 + '@sentry/utils': 7.103.0 dev: false - /@sentry/replay@7.102.0: - resolution: {integrity: sha512-sUIBN4ZY0J5/dQS3KOe5VLykm856KZkTrhV8kmBEylzQhw1BBc8i2ehTILy5ZYh9Ra8uXPTAmtwpvYf/dRDfAg==} + /@sentry/replay@7.103.0: + resolution: {integrity: sha512-I37komyb+DruQG8lPPPOFxLLbOijNXeTxiWLsIn+KFZqRtKqxxQWdNnk56V4YSTpFzxnMEFMRCpXhncuTWu4LA==} engines: {node: '>=12'} dependencies: - '@sentry-internal/tracing': 7.102.0 - '@sentry/core': 7.102.0 - '@sentry/types': 7.102.0 - '@sentry/utils': 7.102.0 + '@sentry-internal/tracing': 7.103.0 + '@sentry/core': 7.103.0 + '@sentry/types': 7.103.0 + '@sentry/utils': 7.103.0 dev: false - /@sentry/tracing@7.102.0: - resolution: {integrity: sha512-2ZLgJw43qY7FjRHnnPGp4rOlPpsrcDGcFlnPIVJgfV14b4bfin1kMMeVgHc9O1S+DTfrkakcPnPnOg1qK1qltg==} + /@sentry/tracing@7.103.0: + resolution: {integrity: sha512-wlL9XidxcjC1dWXj7KSdYMgPgK+ry4dYy+YoW9gqRL+FbS6BJebV73Tni+5zponzCW+LMWP/IgMIB9IZt0WWTQ==} engines: {node: '>=8'} dependencies: - '@sentry-internal/tracing': 7.102.0 + '@sentry-internal/tracing': 7.103.0 dev: false - /@sentry/types@7.102.0: - resolution: {integrity: sha512-FPfFBP0x3LkPARw1/6cWySLq1djIo8ao3Qo2KNBeE9CHdq8bsS1a8zzjJLuWG4Ww+wieLP8/lY3WTgrCz4jowg==} + /@sentry/types@7.103.0: + resolution: {integrity: sha512-NCvKyx8d2AGBQKPARrJemZmZ16DiMo688OEikZg4BbvFNDUzK5Egm2BH0vfLDhbNkU19o3maJowrYo42m8r9Zw==} engines: {node: '>=8'} dev: false - /@sentry/utils@7.102.0: - resolution: {integrity: sha512-cp5KCRe0slOVMwG4iP2Z4UajQkjryRTiFskZ5H7Q3X9R5voM8+DAhiDcIW88GL9NxqyUrAJOjmKdeLK2vM+bdA==} + /@sentry/utils@7.103.0: + resolution: {integrity: sha512-phkUJt3F0UOkVq+M4GfdAh2ewI3ASrNiJddx9aO7GnT0aDwwVBHZltnqt95qgAB8W+BipTSt1dAh8yUbbq1Ceg==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.102.0 + '@sentry/types': 7.103.0 dev: false - /@sentry/vue@7.102.0(vue@3.4.19): - resolution: {integrity: sha512-wH/7/cuhy37W0E6is6nDvfasy3vmNTY1w4AUpirVqaI3iPO+fEEc12RuuRkyRcxmuEBt8x4XxKIPJdMhcKRPug==} + /@sentry/vue@7.103.0(vue@3.4.21): + resolution: {integrity: sha512-o5DlC+B6Yq39KY8SguyX2LWM+daPmjzv5teIx+Vj/MOXRb84gooEqgGvHTO/dlR7qhP89aSw7GRdnjyV+WO5WQ==} engines: {node: '>=8'} peerDependencies: vue: 2.x || 3.x dependencies: - '@sentry/browser': 7.102.0 - '@sentry/core': 7.102.0 - '@sentry/types': 7.102.0 - '@sentry/utils': 7.102.0 - vue: 3.4.19(typescript@5.3.3) + '@sentry/browser': 7.103.0 + '@sentry/core': 7.103.0 + '@sentry/types': 7.103.0 + '@sentry/utils': 7.103.0 + vue: 3.4.21(typescript@5.3.3) dev: false /@sideway/address@4.1.3: @@ -4342,301 +4355,301 @@ packages: defer-to-connect: 1.1.3 dev: true - /@tiptap/core@2.2.3(@tiptap/pm@2.2.3): - resolution: {integrity: sha512-0l3p1/cuaQk8XFf+Ft/ExbUjReGes5Iep7y4nuL/Fzi2S92DZzozY6cosXBHC/Xsqzn6zIkl/gnQTgmTvlmhCQ==} + /@tiptap/core@2.2.4(@tiptap/pm@2.2.4): + resolution: {integrity: sha512-cRrI8IlLIhCE1hacBQzXIC8dsRvGq6a4lYWQK/BaHuZg21CG7szp3Vd8Ix+ra1f5v0xPOT+Hy+QFNQooRMKMCw==} peerDependencies: '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/pm': 2.2.3 + '@tiptap/pm': 2.2.4 dev: false - /@tiptap/extension-blockquote@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-gN23d/ADhTOB0YIM4lR0VrVczdyaXpmIVYYWZ45tQEVJzFWRSIScE9m9NaVqtqwEMpYHyTHxLth0OQutZ91sog==} + /@tiptap/extension-blockquote@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-FrfPnn0VgVrUwWLwja1afX99JGLp6PE9ThVcmri+tLwUZQvTTVcCvHoCdOakav3/nge1+aV4iE3tQdyq1tWI9Q==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-bold@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-bHeFkRY5+Nf2DKupstV8EIVn359tw/9MFwDEDoF9F+Sn/vjuS35vm0OqjXYg/Ya9CQvwl/2oym/fKv5kO+Q6og==} + /@tiptap/extension-bold@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-v3tTLc8YESFZPOGj5ByFr8VbmQ/PTo49T1vsK50VubxIN/5r9cXlKH8kb3dZlZxCxJa3FrXNO/M8rdGBSWQvSg==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-bubble-menu@2.2.4(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): + /@tiptap/extension-bubble-menu@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): resolution: {integrity: sha512-Nx1fS9jcFlhxaTDYlnayz2UulhK6CMaePc36+7PQIVI+u20RhgTCRNr25zKNemvsiM0RPZZVUjlHkxC0l5as1Q==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 tippy.js: 6.3.7 dev: false - /@tiptap/extension-bullet-list@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-BpYg1pIfLE+2LTC90ts53deEWGSmAojhM/jJ84U19qfbfXt/7/KHrZJ4SAMxJSW3pLpy0bIq2XuOuvppOYVR5g==} + /@tiptap/extension-bullet-list@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-z/MPmW8bhRougMuorl6MAQBXeK4rhlP+jBWlNwT+CT8h5IkXqPnDbM1sZeagp2nYfVV6Yc4RWpzimqHHtGnYTA==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-code-block-lowlight@2.2.3(@tiptap/core@2.2.3)(@tiptap/extension-code-block@2.1.12)(@tiptap/pm@2.2.3): - resolution: {integrity: sha512-zVd1Uq0lenbPhw0Mc4ZkrwPblaUp/lNQXGZ8ukhZYQ/JD1oWRA9s0hWQ8jqMi2hp1uTmH5vYFe5bOYqFpoL14g==} + /@tiptap/extension-code-block-lowlight@2.2.4(@tiptap/core@2.2.4)(@tiptap/extension-code-block@2.1.12)(@tiptap/pm@2.2.4): + resolution: {integrity: sha512-FxrpY2Lj6kV6pu5LcaeccE3lqOqvOyFSfMGRV6x1OGOMV9TIFJKIVEIcEhqoiqEnuJZzSmQSx7QZqzOvquZo+A==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/extension-code-block': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/extension-code-block': 2.1.12(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/extension-code-block': 2.1.12(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 dev: false - /@tiptap/extension-code-block@2.1.12(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): + /@tiptap/extension-code-block@2.1.12(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): resolution: {integrity: sha512-RXtSYCVsnk8D+K80uNZShClfZjvv1EgO42JlXLVGWQdIgaNyuOv/6I/Jdf+ZzhnpsBnHufW+6TJjwP5vJPSPHA==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 dev: false - /@tiptap/extension-code@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-ZMp3CrbAV+PVOnPbGmruvlxFENLc+J/Fos8Y4mWvS1nDbrGuu19OKgKimwdzfDBpZVFVnHpEUnDTMBDzDe0hkg==} + /@tiptap/extension-code@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-JB4SJ2mUU/9qXFUf+K5K9szvovnN9AIcCb0f0UlcVBuddKHSqCl3wO3QJgYt44BfQTLMNuyzr+zVqfFd6BNt/g==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-document@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-60Egd9yKb5SzpQlstQAP2A/2a/Qr+A+TblMRKZugrT+NENUhAj6Tx1HxWlblqGu2MsS1iXvQLZ6BQO1jHkL2IQ==} + /@tiptap/extension-document@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-z+05xGK0OFoXV1GL+/8bzcZuWMdMA3+EKwk5c+iziG60VZcvGTF7jBRsZidlu9Oaj0cDwWHCeeo6L9SgSh6i2A==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-dropcursor@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): - resolution: {integrity: sha512-SFvxgVX8/l3H+fV1q6dwmVEwlHuGbaKp1pkQb16/cDiWke/AWOBFTGOIVDfulLI5IiRIL7u3uc+Fy7BXrGDqQw==} + /@tiptap/extension-dropcursor@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): + resolution: {integrity: sha512-IHwkEKmqpqXyJi16h7871NrcIqeyN7I6XRE2qdqi+MhGigVWI8nWHoYbjRKa7K/1uhs5zeRYyDlq5EuZyL6mgA==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 dev: false - /@tiptap/extension-floating-menu@2.2.4(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): + /@tiptap/extension-floating-menu@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): resolution: {integrity: sha512-U25l7PEzOmlAPugNRl8t8lqyhQZS6W/+3f92+FdwW9qXju3i62iX/3OGCC3Gv+vybmQ4fbZmMjvl+VDfenNi3A==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 tippy.js: 6.3.7 dev: false - /@tiptap/extension-gapcursor@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): - resolution: {integrity: sha512-zPVpxembkuOQL/eJ5oAjvZ9Tyv480OpViKrNtOsQh+0nZctmWKnfDntMoWBZiSeW1vsGjkeFIckdeEAQ1KbIxA==} + /@tiptap/extension-gapcursor@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): + resolution: {integrity: sha512-Y6htT/RDSqkQ1UwG2Ia+rNVRvxrKPOs3RbqKHPaWr3vbFWwhHyKhMCvi/FqfI3d5pViVHOZQ7jhb5hT/a0BmNw==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 dev: false - /@tiptap/extension-hard-break@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-P7sP4WBEaQyiiFAswy9lKvaUWUAUwnfTSN3svTAgx0fpU3/ZeVWg+SDi5ve474Ym2oz2eRAr09mNTdWEUsL32Q==} + /@tiptap/extension-hard-break@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-FPvS57GcqHIeLbPKGJa3gnH30Xw+YB1PXXnAWG2MpnMtc2Vtj1l5xaYYBZB+ADdXLAlU0YMbKhFLQO4+pg1Isg==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-heading@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-7atctuvtwPqIAdnBPOhAMsJZd41UPnWN3CktzgzfsfEoplq/86QR1hGIE4JXVB2wAZDmbnKP9Fe8PCNr7Q8JCQ==} + /@tiptap/extension-heading@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-gkq7Ns2FcrOCRq7Q+VRYt5saMt2R9g4REAtWy/jEevJ5UV5vA2AiGnYDmxwAkHutoYU0sAUkjqx37wE0wpamNw==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-history@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): - resolution: {integrity: sha512-S1TUfLtrasyv4zFNlBL302uYaR4wxqR/T36a4d71c0ozr0PsdVc6/f9lfH4aYw4PmS3fzDwJj0PAJ9bb+qDbPw==} + /@tiptap/extension-history@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): + resolution: {integrity: sha512-FDM32XYF5NU4mzh+fJ8w2CyUqv0l2Nl15sd6fOhQkVxSj8t57z+DUXc9ZR3zkH+1RAagYJo/2Gu3e99KpMr0tg==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 dev: false - /@tiptap/extension-horizontal-rule@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): - resolution: {integrity: sha512-pc0J0hBcvj9ymJkFau1W/3L+OhB1PQzMjsx4ZWJvxURL8U7zdDqvYvJjfCA0i5Qw2ZuSVXFACGbEVr6NoCMRAw==} + /@tiptap/extension-horizontal-rule@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): + resolution: {integrity: sha512-iCRHjFQQHApWg3R4fkKkJQhWEOdu1Fdc4YEAukdOXPSg3fg36IwjvsMXjt9SYBtVZ+iio3rORCZGXyMvgCH9uw==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 dev: false - /@tiptap/extension-image@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-IkhISPZ++INAQ3RSwjtJkMIinRyY2g8bqfgyLrc6kXNtfxRGLYS+lizvnI5UUO6X4sRgg/FPfqctAz5bqQBGzA==} + /@tiptap/extension-image@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-xOnqZpnP/fAfmK5AKmXplVQdXBtY5AoZ9B+qllH129aLABaDRzl3e14ZRHC8ahQawOmCe6AOCCXYUBXDOlY5Jg==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-italic@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-SSsFuRnm4Y4Qnc6EuvmA4iarLCt/sg8qkqCKiNPjDUP5JR8HGESeoYVjQzprLHY8jusT9qoC26TP1Sin5vZmWQ==} + /@tiptap/extension-italic@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-qIhGNvWnsQswSgEMRA8jQQjxfkOGNAuNWKEVQX9DPoqAUgknT41hQcAMP8L2+OdACpb2jbVMOO5Cy5Dof2L8/w==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-link@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): - resolution: {integrity: sha512-AKKgkllpj0Po/hi2bVz719OMqyB1nBhKU/Q05yeWVirOYwF2ZwfM4iK2Iab7xWUVhvlyIG3lrWFQL8A30yuqwQ==} + /@tiptap/extension-link@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): + resolution: {integrity: sha512-Qsx0cFZm4dxbkToXs5TcXbSoUdicv8db1gV1DYIZdETqjBm4wFjlzCUP7hPHFlvNfeSy1BzAMRt+RpeuiwvxWQ==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 linkifyjs: 4.1.1 dev: false - /@tiptap/extension-list-item@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-eyfk4f1jOioj+mkIN2m6XQK61MpV0fi17utt8VNx893Td8kS0g7HHuuYMwyjIRtG35ENUaAt7c216JQwnLsrAw==} + /@tiptap/extension-list-item@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-lPLKGKsHpM9ClUa8n7GEUn8pG6HCYU0vFruIy3l2t6jZdHkrgBnYtVGMZ13K8UDnj/hlAlccxku0D0P4mA1Vrg==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-ordered-list@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-YIWpjkHAJN74tY185ZqatlG4+KbXQOdkJpc5cKWqO89gVWLi7+4xwdeeXbTEG64/LOOWS4Q6r1/EJmDy2FCbyA==} + /@tiptap/extension-ordered-list@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-TpFy140O9Af1JciXt+xwqYUXxcJ6YG8zi/B5UDJujp+FH5sCmlYYBBnWxiFMhVaj6yEmA2eafu1qUkic/1X5Aw==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-paragraph@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-4dP+Ecb2iEWW33ckFKjXRnSfEygaFUN19qzc7mUYD8e61ZA8caWL6//uL7DFIz4Q1rchyefbU52gCwTh2P42kQ==} + /@tiptap/extension-paragraph@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-m1KwyvTNJxsq7StbspbcOhxO4Wk4YpElDbqOouWi+H4c8azdpI5Pn96ZqhFeE9bSyjByg6OcB/wqoJsLbeFWdQ==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-placeholder@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): - resolution: {integrity: sha512-Kc+9a/uACY9XBT0uB/qFVpIHm8MzVr0uWA7MCjwDcMneANRLsXEBzWBzyHxRFoNRECfocivV9hQIhuO4i09c9A==} + /@tiptap/extension-placeholder@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): + resolution: {integrity: sha512-UL4Fn9T33SoS7vdI3NnSxBJVeGUIgCIutgXZZ5J8CkcRoDIeS78z492z+6J+qGctHwTd0xUL5NzNJI82HfiTdg==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 dev: false - /@tiptap/extension-strike@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-3wwFk01ociZajRzD08hp4j/4isFUeD6BIkKPDnZeGD5HKPdTOaDciE3dJ3JaZZrRZPPdPV3yMt5hkBOapqEKzQ==} + /@tiptap/extension-strike@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-/a2EwQgA+PpG17V2tVRspcrIY0SN3blwcgM7lxdW4aucGkqSKnf7+91dkhQEwCZ//o8kv9mBCyRoCUcGy6S5Xg==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-table-cell@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-VB+nOMtep9n3g6wU2ISZbBWzru2XIPiYVlyGkclmW3QzeFw3FC8JLY5HDDaSfuBgLL4/Ll17ol9WDkv62jlP/Q==} + /@tiptap/extension-table-cell@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-Dt3FjNjM1Mh2BgEjvx5+s96DiJpC82BdMtqicO3z/Pk0X1bn70ocMuURNR7upfRYI+9YbE3+3wBk/vY1yf7ydw==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-table-header@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-tuuGjfmwuSEHbSMqFMG7BsfgL89KUIvUecukesrs10GJXKh96LKPpFk7JeM0rXAOIDiR6DLF8gfhF1a+OlBpWQ==} + /@tiptap/extension-table-header@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-epRrB/468yGvKb/n6lW3VXWUpjMp3+mKxGWfsXLQncGb1leRbqkgQgsUUYuIEosk+70bjzz6lbfHKQBz408s3g==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-table-row@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-PohdsPNciwD5fN7I0cthOK8204GbYTZVe2YX1S54dCwoTIlzbJiWiFBLlftP0kqveWLTJD4l1CO0tUku39eFEA==} + /@tiptap/extension-table-row@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-VItZ0byY5CVMrcSRrdBjhElHxIq1JQAAli+o3UNYM5rLKHKx4ezeBCUh80wIKvmaAxWsLMs8h/t4crxUE8dyHA==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-table@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): - resolution: {integrity: sha512-k5LwCHribSms7e+oxdqB8S7V7F9VAn2HYncDQnnOm8+v09/JfqX1siWGGKaDeZGZ6BAKgOYx0hOf/RSWSTM8og==} + /@tiptap/extension-table@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): + resolution: {integrity: sha512-9aEFitlcSi33I6a8nGXQ2uNBEx0urYw/C9W4Ygl49YiMzLXtXDBTqSIzVpas1KkKOSN8yaOqB2UiQdbtqGV8fw==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 dev: false - /@tiptap/extension-task-item@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): - resolution: {integrity: sha512-QffmRA56pq4mOb3MnWVOJTiW7NPf54z/iBIlW/8zLKcCKUr8PtC27rs++r5MmtsBrQInRm50b+ibKINyOixd+g==} + /@tiptap/extension-task-item@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): + resolution: {integrity: sha512-Ixzv7bPcgrWelSD0Jy6yAlHxmGWpD5lPt6Ey4POYy7u98duyUFOBMHLcsV24ipQsRacuB+htgmuqOrkiL+hg7w==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 dev: false - /@tiptap/extension-task-list@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-ruwJ//jPjIT60p42goqqApCYsjZHk+E15HajEycdpu9gOqEiVh/Hsn8z4g3ZYwgMF8SuyU4mm11K05xYtoG40A==} + /@tiptap/extension-task-list@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-URh1Yzj/YZBOMkobK4/U8s1QYwIIqHm4b0YadLPPZx9IzTjyV/2bvIakphCmBtxWxeTXW5TbO9eNod3qatq21w==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-text@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-BrWGCkmuzVcsNy7dSCfJyVwedPzeNz6BR/OUNzM8Mqt2KSxfoIRy7cg16HvFB4YW+ijrM9XUqDIFvqYI0TY+Jg==} + /@tiptap/extension-text@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-NlKHMPnRJXB+0AGtDlU0P2Pg+SdesA2lMMd7JzDUgJgL7pX2jOb8eUqSeOjFKuSzFSqYfH6C3o6mQiNhuQMv+g==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-typography@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-PCxb5lJkx/OguqgnrrhKdM8ayeH2EKrcCbbCMTScLEYSVKs0nkTt7p+PwugsZW5hxeuwhIOKgLSPHE4tSYol9w==} + /@tiptap/extension-typography@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-1gmvr74uk44Wzxd6QI+dKz/M//xaD15yYwUtcRc9+ohbfvCqtRl3XDVoxl3MQmDMljcui5kMMaRcFNvW1Kujvg==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/extension-underline@2.2.3(@tiptap/core@2.2.3): - resolution: {integrity: sha512-Y6PTaXmDFay39+Knk77T+Ezc5vuC/gFxZFD6cQhjctZHMJ2QMAguMKWtBVaSs78HBkKnwTU9EViAFBurz++Geg==} + /@tiptap/extension-underline@2.2.4(@tiptap/core@2.2.4): + resolution: {integrity: sha512-jCHgIJMwtXlGHVy/j3L8/QvglHCikkHJw7YS5yf8E/8HlPh1tZfVy/IxdgacDOpUN30X+UPJZQDdVKymafgwdA==} peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) dev: false - /@tiptap/pm@2.2.3: - resolution: {integrity: sha512-jYZX+0fjN+a1J8qY72Poz1LK6X6oHVQkJIq6qzcx3rm0voYZNVRzP2GIfzstncZiEqRXABHY3mWfOi2I4K9tQA==} + /@tiptap/pm@2.2.4: + resolution: {integrity: sha512-Po0klR165zgtinhVp1nwMubjyKx6gAY9kH3IzcniYLCkqhPgiqnAcCr61TBpp4hfK8YURBS4ihvCB1dyfCyY8A==} dependencies: prosemirror-changeset: 2.2.1 prosemirror-collab: 1.3.1 @@ -4658,28 +4671,28 @@ packages: prosemirror-view: 1.32.7 dev: false - /@tiptap/suggestion@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3): - resolution: {integrity: sha512-pMInbk8+rYNaCz4oT/uS498mxSGIJXU32mkXv7wdDqMT2nnZQ2AHtJDUtMuB1RX+DS4ll9vdzrKqQHSW5t2ybQ==} + /@tiptap/suggestion@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4): + resolution: {integrity: sha512-g6HHsKM6K3asW+ZlwMYyLCRqCRaswoliZOQofY4iZt5ru5HNTSzm3YW4XSyW5RGXJIuc319yyrOFgtJ3Fyu5rQ==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 dev: false - /@tiptap/vue-3@2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3)(vue@3.4.19): - resolution: {integrity: sha512-TC+pncpxP6GHgM+qvX/1mfT+Xl3OlEekZqjetNJC/MfFM55OL5dIEu5kVjOiRsGQ/TWgwBGPrRYEE0Y1D6FuBA==} + /@tiptap/vue-3@2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4)(vue@3.4.21): + resolution: {integrity: sha512-6Rue56OUmDl/OT07QcLsH1UvYGUmV8OFSDCrLrUyku/2lAYHwHz6+KhAB5paZt70nEGIw03G1KCT074negj6NQ==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 vue: ^3.0.0 dependencies: - '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) - '@tiptap/extension-bubble-menu': 2.2.4(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) - '@tiptap/extension-floating-menu': 2.2.4(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3) - '@tiptap/pm': 2.2.3 - vue: 3.4.19(typescript@5.3.3) + '@tiptap/core': 2.2.4(@tiptap/pm@2.2.4) + '@tiptap/extension-bubble-menu': 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) + '@tiptap/extension-floating-menu': 2.2.4(@tiptap/core@2.2.4)(@tiptap/pm@2.2.4) + '@tiptap/pm': 2.2.4 + vue: 3.4.21(typescript@5.3.3) dev: false /@tootallnate/once@2.0.0: @@ -4746,7 +4759,7 @@ packages: /@types/fs-extra@9.0.13: resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.22 dev: true /@types/har-format@1.2.10: @@ -4770,7 +4783,7 @@ packages: /@types/keyv@3.1.3: resolution: {integrity: sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.22 dev: true /@types/linkify-it@3.0.2: @@ -4811,8 +4824,8 @@ packages: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} dev: true - /@types/node@20.11.10: - resolution: {integrity: sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg==} + /@types/node@20.11.22: + resolution: {integrity: sha512-/G+IxWxma6V3E+pqK1tSl2Fo1kl41pK1yeCyDsgkF9WlVAme4j5ISYM2zR11bgLFJGLN5sVK40T4RJNuiZbEjA==} dependencies: undici-types: 5.26.5 dev: true @@ -4832,20 +4845,20 @@ packages: /@types/postcss-preset-env@7.7.0: resolution: {integrity: sha512-biD8MwSiZo1Nztn1cIBPMcKNKzgFyU05AB96HIF9y3G4f9vdx2O60DHCSpWXChTp6mOEGu15fqIw2DetVVjghw==} dependencies: - autoprefixer: 10.4.17(postcss@8.4.33) - postcss: 8.4.33 + autoprefixer: 10.4.17(postcss@8.4.35) + postcss: 8.4.35 dev: true /@types/resolve@1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.22 dev: true /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.22 dev: true /@types/semver@7.5.0: @@ -4860,8 +4873,8 @@ packages: resolution: {integrity: sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==} dev: true - /@types/sortablejs@1.15.7: - resolution: {integrity: sha512-PvgWCx1Lbgm88FdQ6S7OGvLIjWS66mudKPlfdrWil0TjsO5zmoZmzoKiiwRShs1dwPgrlkr0N4ewuy0/+QUXYQ==} + /@types/sortablejs@1.15.8: + resolution: {integrity: sha512-b79830lW+RZfwaztgs1aVPgbasJ8e7AXtZYHTELNXZPsERt4ymJdjV4OccDbHQAvHrCcFpbF78jkm0R6h/pZVg==} dev: true /@types/tern@0.23.4: @@ -4894,11 +4907,11 @@ packages: resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} requiresBuild: true dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.22 dev: true optional: true - /@typescript-eslint/eslint-plugin@6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.56.0)(typescript@5.3.3): + /@typescript-eslint/eslint-plugin@6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.57.0)(typescript@5.3.3): resolution: {integrity: sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -4910,25 +4923,25 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.6.2 - '@typescript-eslint/parser': 6.20.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.20.0(eslint@8.57.0)(typescript@5.3.3) '@typescript-eslint/scope-manager': 6.20.0 - '@typescript-eslint/type-utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/type-utils': 6.20.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.20.0(eslint@8.57.0)(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.20.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.56.0 + eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.2.4 natural-compare: 1.4.0 - semver: 7.6.0 + semver: 7.5.4 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/eslint-plugin@7.0.1(@typescript-eslint/parser@7.0.1)(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-OLvgeBv3vXlnnJGIAgCLYKjgMEU+wBGj07MQ/nxAaON+3mLzX7mJbhRYrVGiVvFiXtwFlkcBa/TtmglHy0UbzQ==} + /@typescript-eslint/eslint-plugin@7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3): + resolution: {integrity: sha512-j6vT/kCulhG5wBmGtstKeiVr1rdXE4nk+DT1k6trYkwlrvW9eOF5ZbgKnd/YR6PcM4uTEXa0h6Fcvf6X7Dxl0w==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -4939,24 +4952,24 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.6.2 - '@typescript-eslint/parser': 7.0.1(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/scope-manager': 7.0.1 - '@typescript-eslint/type-utils': 7.0.1(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/utils': 7.0.1(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 7.0.1 + '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 7.1.0 + '@typescript-eslint/type-utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 7.1.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.56.0 + eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.2.4 natural-compare: 1.4.0 - semver: 7.6.0 + semver: 7.5.4 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.20.0(eslint@8.56.0)(typescript@5.3.3): + /@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.3.3): resolution: {integrity: sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -4971,14 +4984,14 @@ packages: '@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.20.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.56.0 + eslint: 8.57.0 typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@7.0.1(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-8GcRRZNzaHxKzBPU3tKtFNing571/GwPBeCvmAUw0yBtfE2XVd0zFKJIMSWkHJcPQi0ekxjIts6L/rrZq5cxGQ==} + /@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3): + resolution: {integrity: sha512-V1EknKUubZ1gWFjiOZhDSNToOjs63/9O0puCgGS8aDOgpZY326fzFu15QAUjwaXzRZjf/qdsdBrckYdv9YxB8w==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^8.56.0 @@ -4987,12 +5000,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 7.0.1 - '@typescript-eslint/types': 7.0.1 - '@typescript-eslint/typescript-estree': 7.0.1(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 7.0.1 + '@typescript-eslint/scope-manager': 7.1.0 + '@typescript-eslint/types': 7.1.0 + '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 7.1.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.56.0 + eslint: 8.57.0 typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -5006,15 +5019,15 @@ packages: '@typescript-eslint/visitor-keys': 6.20.0 dev: true - /@typescript-eslint/scope-manager@7.0.1: - resolution: {integrity: sha512-v7/T7As10g3bcWOOPAcbnMDuvctHzCFYCG/8R4bK4iYzdFqsZTbXGln0cZNVcwQcwewsYU2BJLay8j0/4zOk4w==} + /@typescript-eslint/scope-manager@7.1.0: + resolution: {integrity: sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 7.0.1 - '@typescript-eslint/visitor-keys': 7.0.1 + '@typescript-eslint/types': 7.1.0 + '@typescript-eslint/visitor-keys': 7.1.0 dev: true - /@typescript-eslint/type-utils@6.20.0(eslint@8.56.0)(typescript@5.3.3): + /@typescript-eslint/type-utils@6.20.0(eslint@8.57.0)(typescript@5.3.3): resolution: {integrity: sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -5025,17 +5038,17 @@ packages: optional: true dependencies: '@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3) - '@typescript-eslint/utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.20.0(eslint@8.57.0)(typescript@5.3.3) debug: 4.3.4(supports-color@8.1.1) - eslint: 8.56.0 + eslint: 8.57.0 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/type-utils@7.0.1(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-YtT9UcstTG5Yqy4xtLiClm1ZpM/pWVGFnkAa90UfdkkZsR1eP2mR/1jbHeYp8Ay1l1JHPyGvoUYR6o3On5Nhmw==} + /@typescript-eslint/type-utils@7.1.0(eslint@8.57.0)(typescript@5.3.3): + resolution: {integrity: sha512-UZIhv8G+5b5skkcuhgvxYWHjk7FW7/JP5lPASMEUoliAPwIH/rxoUSQPia2cuOj9AmDZmwUl1usKm85t5VUMew==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^8.56.0 @@ -5044,10 +5057,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 7.0.1(typescript@5.3.3) - '@typescript-eslint/utils': 7.0.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3) + '@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3) debug: 4.3.4(supports-color@8.1.1) - eslint: 8.56.0 + eslint: 8.57.0 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: @@ -5059,8 +5072,8 @@ packages: engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/types@7.0.1: - resolution: {integrity: sha512-uJDfmirz4FHib6ENju/7cz9SdMSkeVvJDK3VcMFvf/hAShg8C74FW+06MaQPODHfDJp/z/zHfgawIJRjlu0RLg==} + /@typescript-eslint/types@7.1.0: + resolution: {integrity: sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==} engines: {node: ^16.0.0 || >=18.0.0} dev: true @@ -5079,15 +5092,15 @@ packages: globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.6.0 + semver: 7.5.4 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/typescript-estree@7.0.1(typescript@5.3.3): - resolution: {integrity: sha512-SO9wHb6ph0/FN5OJxH4MiPscGah5wjOd0RRpaLvuBv9g8565Fgu0uMySFEPqwPHiQU90yzJ2FjRYKGrAhS1xig==} + /@typescript-eslint/typescript-estree@7.1.0(typescript@5.3.3): + resolution: {integrity: sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -5095,52 +5108,52 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 7.0.1 - '@typescript-eslint/visitor-keys': 7.0.1 + '@typescript-eslint/types': 7.1.0 + '@typescript-eslint/visitor-keys': 7.1.0 debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.6.0 + semver: 7.5.4 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@6.20.0(eslint@8.56.0)(typescript@5.3.3): + /@typescript-eslint/utils@6.20.0(eslint@8.57.0)(typescript@5.3.3): resolution: {integrity: sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.0 '@typescript-eslint/scope-manager': 6.20.0 '@typescript-eslint/types': 6.20.0 '@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3) - eslint: 8.56.0 - semver: 7.6.0 + eslint: 8.57.0 + semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/utils@7.0.1(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-oe4his30JgPbnv+9Vef1h48jm0S6ft4mNwi9wj7bX10joGn07QRfqIqFHoMiajrtoU88cIhXf8ahwgrcbNLgPA==} + /@typescript-eslint/utils@7.1.0(eslint@8.57.0)(typescript@5.3.3): + resolution: {integrity: sha512-WUFba6PZC5OCGEmbweGpnNJytJiLG7ZvDBJJoUcX4qZYf1mGZ97mO2Mps6O2efxJcJdRNpqweCistDbZMwIVHw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^8.56.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 7.0.1 - '@typescript-eslint/types': 7.0.1 - '@typescript-eslint/typescript-estree': 7.0.1(typescript@5.3.3) - eslint: 8.56.0 - semver: 7.6.0 + '@typescript-eslint/scope-manager': 7.1.0 + '@typescript-eslint/types': 7.1.0 + '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3) + eslint: 8.57.0 + semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript @@ -5154,11 +5167,11 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@typescript-eslint/visitor-keys@7.0.1: - resolution: {integrity: sha512-hwAgrOyk++RTXrP4KzCg7zB2U0xt7RUU0ZdMSCsqF3eKUwkdXUMyTb0qdCuji7VIbcpG62kKTU9M1J1c9UpFBw==} + /@typescript-eslint/visitor-keys@7.1.0: + resolution: {integrity: sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 7.0.1 + '@typescript-eslint/types': 7.1.0 eslint-visitor-keys: 3.4.3 dev: true @@ -5166,8 +5179,8 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@vitejs/plugin-legacy@5.3.0(esbuild@0.20.0)(terser@5.24.0)(vite@5.0.12): - resolution: {integrity: sha512-BhW+WcJmEgW5G/1UQRiVQ7wz9/ZPnxqzExT9n0zAk4RlqQQ/26udIeXzdU8+03AGnaF61wmZlCspexgEnxFWMA==} + /@vitejs/plugin-legacy@5.3.1(esbuild@0.20.1)(terser@5.24.0)(vite@5.1.4): + resolution: {integrity: sha512-ymCuZo8Bu7gSO85I3E/3SNnaQ64gFdVpTqxqhl8YeasJChDxN8D3IKYByC+AsxwoeO2AE59wy4PPILM/A03TIQ==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: terser: ^5.4.0 @@ -5175,62 +5188,62 @@ packages: dependencies: '@babel/core': 7.23.9 '@babel/preset-env': 7.23.9(@babel/core@7.23.9) - browserslist: 4.22.3 + browserslist: 4.23.0 core-js: 3.36.0 - esbuild-plugin-browserslist: 0.10.0(browserslist@4.22.3)(esbuild@0.20.0) + esbuild-plugin-browserslist: 0.11.1(browserslist@4.23.0)(esbuild@0.20.1) magic-string: 0.30.7 regenerator-runtime: 0.14.1 systemjs: 6.14.3 terser: 5.24.0 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) transitivePeerDependencies: - esbuild - supports-color dev: true - /@vitejs/plugin-vue@5.0.3(vite@5.0.12)(vue@3.4.19): - resolution: {integrity: sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA==} + /@vitejs/plugin-vue@5.0.4(vite@5.1.4)(vue@3.4.21): + resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 vue: ^3.2.25 dependencies: - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) - vue: 3.4.19(typescript@5.3.3) + vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vue: 3.4.21(typescript@5.3.3) dev: true - /@vitest/expect@1.2.2: - resolution: {integrity: sha512-3jpcdPAD7LwHUUiT2pZTj2U82I2Tcgg2oVPvKxhn6mDI2On6tfvPQTjAI4628GUGDZrCm4Zna9iQHm5cEexOAg==} + /@vitest/expect@1.3.1: + resolution: {integrity: sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==} dependencies: - '@vitest/spy': 1.2.2 - '@vitest/utils': 1.2.2 + '@vitest/spy': 1.3.1 + '@vitest/utils': 1.3.1 chai: 4.3.10 dev: true - /@vitest/runner@1.2.2: - resolution: {integrity: sha512-JctG7QZ4LSDXr5CsUweFgcpEvrcxOV1Gft7uHrvkQ+fsAVylmWQvnaAr/HDp3LAH1fztGMQZugIheTWjaGzYIg==} + /@vitest/runner@1.3.1: + resolution: {integrity: sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg==} dependencies: - '@vitest/utils': 1.2.2 + '@vitest/utils': 1.3.1 p-limit: 5.0.0 pathe: 1.1.1 dev: true - /@vitest/snapshot@1.2.2: - resolution: {integrity: sha512-SmGY4saEw1+bwE1th6S/cZmPxz/Q4JWsl7LvbQIky2tKE35US4gd0Mjzqfr84/4OD0tikGWaWdMja/nWL5NIPA==} + /@vitest/snapshot@1.3.1: + resolution: {integrity: sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ==} dependencies: magic-string: 0.30.7 pathe: 1.1.1 pretty-format: 29.7.0 dev: true - /@vitest/spy@1.2.2: - resolution: {integrity: sha512-k9Gcahssw8d7X3pSLq3e3XEu/0L78mUkCjivUqCQeXJm9clfXR/Td8+AP+VC1O6fKPIDLcHDTAmBOINVuv6+7g==} + /@vitest/spy@1.3.1: + resolution: {integrity: sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==} dependencies: tinyspy: 2.2.0 dev: true - /@vitest/utils@1.2.2: - resolution: {integrity: sha512-WKITBHLsBHlpjnDQahr+XK6RE7MiAsgrIkr0pGhQ9ygoxBfUeG0lUG5iLlzqjmKSlBv3+j5EGsriBzh+C3Tq9g==} + /@vitest/utils@1.3.1: + resolution: {integrity: sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==} dependencies: diff-sequences: 29.6.3 estree-walker: 3.0.3 @@ -5276,11 +5289,11 @@ packages: source-map-js: 1.0.2 dev: true - /@vue/compiler-core@3.4.19: - resolution: {integrity: sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==} + /@vue/compiler-core@3.4.21: + resolution: {integrity: sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==} dependencies: '@babel/parser': 7.23.9 - '@vue/shared': 3.4.19 + '@vue/shared': 3.4.21 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.0.2 @@ -5299,11 +5312,11 @@ packages: '@vue/shared': 3.4.14 dev: true - /@vue/compiler-dom@3.4.19: - resolution: {integrity: sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==} + /@vue/compiler-dom@3.4.21: + resolution: {integrity: sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==} dependencies: - '@vue/compiler-core': 3.4.19 - '@vue/shared': 3.4.19 + '@vue/compiler-core': 3.4.21 + '@vue/shared': 3.4.21 /@vue/compiler-sfc@3.3.13: resolution: {integrity: sha512-DQVmHEy/EKIgggvnGRLx21hSqnr1smUS9Aq8tfxiiot8UR0/pXKHN9k78/qQ7etyQTFj5em5nruODON7dBeumw==} @@ -5316,21 +5329,21 @@ packages: '@vue/shared': 3.3.13 estree-walker: 2.0.2 magic-string: 0.30.7 - postcss: 8.4.33 + postcss: 8.4.35 source-map-js: 1.0.2 dev: false - /@vue/compiler-sfc@3.4.19: - resolution: {integrity: sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==} + /@vue/compiler-sfc@3.4.21: + resolution: {integrity: sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==} dependencies: '@babel/parser': 7.23.9 - '@vue/compiler-core': 3.4.19 - '@vue/compiler-dom': 3.4.19 - '@vue/compiler-ssr': 3.4.19 - '@vue/shared': 3.4.19 + '@vue/compiler-core': 3.4.21 + '@vue/compiler-dom': 3.4.21 + '@vue/compiler-ssr': 3.4.21 + '@vue/shared': 3.4.21 estree-walker: 2.0.2 magic-string: 0.30.7 - postcss: 8.4.33 + postcss: 8.4.35 source-map-js: 1.0.2 /@vue/compiler-ssr@3.3.13: @@ -5340,11 +5353,11 @@ packages: '@vue/shared': 3.3.13 dev: false - /@vue/compiler-ssr@3.4.19: - resolution: {integrity: sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==} + /@vue/compiler-ssr@3.4.21: + resolution: {integrity: sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==} dependencies: - '@vue/compiler-dom': 3.4.19 - '@vue/shared': 3.4.19 + '@vue/compiler-dom': 3.4.21 + '@vue/shared': 3.4.21 /@vue/devtools-api@6.5.0: resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} @@ -5354,7 +5367,7 @@ packages: resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==} dev: false - /@vue/eslint-config-typescript@12.0.0(eslint-plugin-vue@9.20.1)(eslint@8.56.0)(typescript@5.3.3): + /@vue/eslint-config-typescript@12.0.0(eslint-plugin-vue@9.22.0)(eslint@8.57.0)(typescript@5.3.3): resolution: {integrity: sha512-StxLFet2Qe97T8+7L8pGlhYBBr8Eg05LPuTDVopQV6il+SK6qqom59BA/rcFipUef2jD8P2X44Vd8tMFytfvlg==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: @@ -5365,12 +5378,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/parser': 6.20.0(eslint@8.56.0)(typescript@5.3.3) - eslint: 8.56.0 - eslint-plugin-vue: 9.20.1(eslint@8.56.0) + '@typescript-eslint/eslint-plugin': 6.20.0(@typescript-eslint/parser@6.20.0)(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.20.0(eslint@8.57.0)(typescript@5.3.3) + eslint: 8.57.0 + eslint-plugin-vue: 9.22.0(eslint@8.57.0) typescript: 5.3.3 - vue-eslint-parser: 9.3.1(eslint@8.56.0) + vue-eslint-parser: 9.3.1(eslint@8.57.0) transitivePeerDependencies: - supports-color dev: true @@ -5405,32 +5418,32 @@ packages: magic-string: 0.30.7 dev: false - /@vue/reactivity@3.4.19: - resolution: {integrity: sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==} + /@vue/reactivity@3.4.21: + resolution: {integrity: sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==} dependencies: - '@vue/shared': 3.4.19 + '@vue/shared': 3.4.21 - /@vue/runtime-core@3.4.19: - resolution: {integrity: sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==} + /@vue/runtime-core@3.4.21: + resolution: {integrity: sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==} dependencies: - '@vue/reactivity': 3.4.19 - '@vue/shared': 3.4.19 + '@vue/reactivity': 3.4.21 + '@vue/shared': 3.4.21 - /@vue/runtime-dom@3.4.19: - resolution: {integrity: sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==} + /@vue/runtime-dom@3.4.21: + resolution: {integrity: sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==} dependencies: - '@vue/runtime-core': 3.4.19 - '@vue/shared': 3.4.19 + '@vue/runtime-core': 3.4.21 + '@vue/shared': 3.4.21 csstype: 3.1.3 - /@vue/server-renderer@3.4.19(vue@3.4.19): - resolution: {integrity: sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==} + /@vue/server-renderer@3.4.21(vue@3.4.21): + resolution: {integrity: sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==} peerDependencies: - vue: 3.4.19 + vue: 3.4.21 dependencies: - '@vue/compiler-ssr': 3.4.19 - '@vue/shared': 3.4.19 - vue: 3.4.19(typescript@5.3.3) + '@vue/compiler-ssr': 3.4.21 + '@vue/shared': 3.4.21 + vue: 3.4.21(typescript@5.3.3) /@vue/shared@3.3.13: resolution: {integrity: sha512-/zYUwiHD8j7gKx2argXEMCUXVST6q/21DFU0sTfNX0URJroCe3b1UF6vLJ3lQDfLNIiiRl2ONp7Nh5UVWS6QnA==} @@ -5440,10 +5453,10 @@ packages: resolution: {integrity: sha512-nmi3BtLpvqXAWoRZ6HQ+pFJOHBU4UnH3vD3opgmwXac7vhaHKA9nj1VeGjMggdB9eLtW83eHyPCmOU1qzdsC7Q==} dev: true - /@vue/shared@3.4.19: - resolution: {integrity: sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==} + /@vue/shared@3.4.21: + resolution: {integrity: sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==} - /@vue/test-utils@2.4.4(vue@3.4.19): + /@vue/test-utils@2.4.4(vue@3.4.21): resolution: {integrity: sha512-8jkRxz8pNhClAf4Co4ZrpAoFISdvT3nuSkUlY6Ys6rmTpw3DMWG/X3mw3gQ7QJzgCZO9f+zuE2kW57fi09MW7Q==} peerDependencies: '@vue/server-renderer': ^3.0.1 @@ -5453,7 +5466,7 @@ packages: optional: true dependencies: js-beautify: 1.14.9 - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) vue-component-type-helpers: 1.8.22 dev: true @@ -5461,64 +5474,64 @@ packages: resolution: {integrity: sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==} dev: true - /@vueuse/core@10.8.0(vue@3.4.19): - resolution: {integrity: sha512-G9Ok9fjx10TkNIPn8V1dJmK1NcdJCtYmDRyYiTMUyJ1p0Tywc1zmOoCQ2xhHYyz8ULBU4KjIJQ9n+Lrty74iVw==} + /@vueuse/core@10.9.0(vue@3.4.21): + resolution: {integrity: sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==} dependencies: '@types/web-bluetooth': 0.0.20 - '@vueuse/metadata': 10.8.0 - '@vueuse/shared': 10.8.0(vue@3.4.19) - vue-demi: 0.14.7(vue@3.4.19) + '@vueuse/metadata': 10.9.0 + '@vueuse/shared': 10.9.0(vue@3.4.21) + vue-demi: 0.14.7(vue@3.4.21) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/core@9.13.0(vue@3.4.19): + /@vueuse/core@9.13.0(vue@3.4.21): resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==} dependencies: '@types/web-bluetooth': 0.0.16 '@vueuse/metadata': 9.13.0 - '@vueuse/shared': 9.13.0(vue@3.4.19) - vue-demi: 0.14.6(vue@3.4.19) + '@vueuse/shared': 9.13.0(vue@3.4.21) + vue-demi: 0.14.6(vue@3.4.21) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/metadata@10.8.0: - resolution: {integrity: sha512-Nim/Vle5OgXcXhAvGOgkJQXB1Yb+Kq/fMbLuv3YYDYbiQrwr39ljuD4k9fPeq4yUyokYRo2RaNQmbbIMWB/9+w==} + /@vueuse/metadata@10.9.0: + resolution: {integrity: sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==} dev: false /@vueuse/metadata@9.13.0: resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==} dev: false - /@vueuse/router@10.8.0(vue-router@4.3.0)(vue@3.4.19): - resolution: {integrity: sha512-5WI5QYEs2XLC01JGrOC8dMDAkNsp3rOvvwed2O2gHUQt/OQ3cu3wLu8RfI0CZfoetDrj/LDcIYDcGhh70ST6+Q==} + /@vueuse/router@10.9.0(vue-router@4.3.0)(vue@3.4.21): + resolution: {integrity: sha512-MOmrCMQlRuPS4PExE1hy8T0XbZUXaNbEuh7CAG5mC8kdvdgANQMkdvJ7vIEOP27n5mXK/4YjvXJOZSsur4E0QQ==} peerDependencies: vue-router: '>=4.0.0-rc.1' dependencies: - '@vueuse/shared': 10.8.0(vue@3.4.19) - vue-demi: 0.14.7(vue@3.4.19) - vue-router: 4.3.0(vue@3.4.19) + '@vueuse/shared': 10.9.0(vue@3.4.21) + vue-demi: 0.14.7(vue@3.4.21) + vue-router: 4.3.0(vue@3.4.21) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/shared@10.8.0(vue@3.4.19): - resolution: {integrity: sha512-dUdy6zwHhULGxmr9YUg8e+EnB39gcM4Fe2oKBSrh3cOsV30JcMPtsyuspgFCUo5xxFNaeMf/W2yyKfST7Bg8oQ==} + /@vueuse/shared@10.9.0(vue@3.4.21): + resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==} dependencies: - vue-demi: 0.14.7(vue@3.4.19) + vue-demi: 0.14.7(vue@3.4.21) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/shared@9.13.0(vue@3.4.19): + /@vueuse/shared@9.13.0(vue@3.4.21): resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} dependencies: - vue-demi: 0.14.6(vue@3.4.19) + vue-demi: 0.14.6(vue@3.4.21) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -5700,19 +5713,19 @@ packages: engines: {node: '>= 4.0.0'} dev: true - /autoprefixer@10.4.17(postcss@8.4.33): + /autoprefixer@10.4.17(postcss@8.4.35): resolution: {integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: - browserslist: 4.22.3 - caniuse-lite: 1.0.30001581 + browserslist: 4.23.0 + caniuse-lite: 1.0.30001591 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true @@ -5884,15 +5897,15 @@ packages: dependencies: fill-range: 7.0.1 - /browserslist@4.22.3: - resolution: {integrity: sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==} + /browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001581 + caniuse-lite: 1.0.30001591 electron-to-chromium: 1.4.685 node-releases: 2.0.14 - update-browserslist-db: 1.0.13(browserslist@4.22.3) + update-browserslist-db: 1.0.13(browserslist@4.23.0) dev: true /buffer-crc32@0.2.13: @@ -5975,8 +5988,8 @@ packages: engines: {node: '>=6'} dev: true - /caniuse-lite@1.0.30001581: - resolution: {integrity: sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ==} + /caniuse-lite@1.0.30001591: + resolution: {integrity: sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==} dev: true /capital-case@1.0.4: @@ -6296,7 +6309,7 @@ packages: /core-js-compat@3.34.0: resolution: {integrity: sha512-4ZIyeNbW/Cn1wkMMDy+mvrRUxrwFNjKwbhCfQpDd+eLgYipDqp8oGFGtLmhh18EDPKA0g3VUBYOxQGGwvWLVpA==} dependencies: - browserslist: 4.22.3 + browserslist: 4.23.0 dev: true /core-js@3.36.0: @@ -6333,35 +6346,35 @@ packages: engines: {node: '>=8'} dev: true - /css-blank-pseudo@6.0.1(postcss@8.4.33): + /css-blank-pseudo@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-goSnEITByxTzU4Oh5oJZrEWudxTqk7L6IXj1UW69pO6Hv0UdX+Vsrt02FFu5DweRh2bLu6WpX/+zsQCu5O1gKw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 - postcss-selector-parser: 6.0.15 + postcss: 8.4.35 + postcss-selector-parser: 6.0.13 dev: true - /css-has-pseudo@6.0.1(postcss@8.4.33): - resolution: {integrity: sha512-WwoVKqNxApfEI7dWFyaHoeFCcUPD+lPyjL6lNpRUNX7IyIUuVpawOTwwA5D0ZR6V2xQZonNPVj8kEcxzEaAQfQ==} + /css-has-pseudo@6.0.2(postcss@8.4.35): + resolution: {integrity: sha512-Z2Qm5yyOvJRTy6THdUlnGIX6PW/1wOc4FHWlfkcBkfkpZ3oz6lPdG+h+J7t1HZHT4uSSVR8XatXiMpqMUADXow==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.15) - postcss: 8.4.33 - postcss-selector-parser: 6.0.15 + '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.13) + postcss: 8.4.35 + postcss-selector-parser: 6.0.13 postcss-value-parser: 4.2.0 dev: true - /css-prefers-color-scheme@9.0.1(postcss@8.4.33): + /css-prefers-color-scheme@9.0.1(postcss@8.4.35): resolution: {integrity: sha512-iFit06ochwCKPRiWagbTa1OAWCvWWVdEnIFd8BaRrgO8YrrNh4RAWUQTFcYX5tdFZgFl1DJ3iiULchZyEbnF4g==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true /css-select@4.2.1: @@ -6445,8 +6458,8 @@ packages: /csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - /cypress@13.6.3: - resolution: {integrity: sha512-d/pZvgwjAyZsoyJ3FOsJT5lDsqnxQ/clMqnNc++rkHjbkkiF2h9s0JsZSyyH4QXhVFW3zPFg82jD25roFLOdZA==} + /cypress@13.6.6: + resolution: {integrity: sha512-S+2S9S94611hXimH9a3EAYt81QM913ZVA03pUmGDfLTFa5gyp85NJ8dJGSlEAEmyRsYkioS1TtnWtbv/Fzt11A==} engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} hasBin: true requiresBuild: true @@ -6488,7 +6501,7 @@ packages: process: 0.11.10 proxy-from-env: 1.0.0 request-progress: 3.0.0 - semver: 7.6.0 + semver: 7.5.4 supports-color: 8.1.1 tmp: 0.2.1 untildify: 4.0.0 @@ -6870,16 +6883,16 @@ packages: is-symbol: 1.0.4 dev: true - /esbuild-plugin-browserslist@0.10.0(browserslist@4.22.3)(esbuild@0.20.0): - resolution: {integrity: sha512-rZWFcp3l+73xDiJB+Vl9UqP1VVs+L4E0lygbwJl6UTmW2qQago7DLT56hBu0vocH/TtZsAcRHj0+qHqkkB5Gww==} + /esbuild-plugin-browserslist@0.11.1(browserslist@4.23.0)(esbuild@0.20.1): + resolution: {integrity: sha512-yNdZRdDBEbm0PT4q2bJBhXvnwakXG5mG8ipiwGe5SRDPnKa7L7kQm2tHuBMowBtcFz6kRtZTv5njK7PJwU+tCQ==} engines: {node: '>=18'} peerDependencies: browserslist: ^4.21.8 - esbuild: ~0.19.2 + esbuild: ~0.20.0 dependencies: - browserslist: 4.22.3 + browserslist: 4.23.0 debug: 4.3.4(supports-color@8.1.1) - esbuild: 0.20.0 + esbuild: 0.20.1 zod: 3.22.4 transitivePeerDependencies: - supports-color @@ -6916,35 +6929,35 @@ packages: '@esbuild/win32-x64': 0.19.12 dev: true - /esbuild@0.20.0: - resolution: {integrity: sha512-6iwE3Y2RVYCME1jLpBqq7LQWK3MW6vjV2bZy6gt/WrqkY+WE74Spyc0ThAOYpMtITvnjX09CrC6ym7A/m9mebA==} + /esbuild@0.20.1: + resolution: {integrity: sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/aix-ppc64': 0.20.0 - '@esbuild/android-arm': 0.20.0 - '@esbuild/android-arm64': 0.20.0 - '@esbuild/android-x64': 0.20.0 - '@esbuild/darwin-arm64': 0.20.0 - '@esbuild/darwin-x64': 0.20.0 - '@esbuild/freebsd-arm64': 0.20.0 - '@esbuild/freebsd-x64': 0.20.0 - '@esbuild/linux-arm': 0.20.0 - '@esbuild/linux-arm64': 0.20.0 - '@esbuild/linux-ia32': 0.20.0 - '@esbuild/linux-loong64': 0.20.0 - '@esbuild/linux-mips64el': 0.20.0 - '@esbuild/linux-ppc64': 0.20.0 - '@esbuild/linux-riscv64': 0.20.0 - '@esbuild/linux-s390x': 0.20.0 - '@esbuild/linux-x64': 0.20.0 - '@esbuild/netbsd-x64': 0.20.0 - '@esbuild/openbsd-x64': 0.20.0 - '@esbuild/sunos-x64': 0.20.0 - '@esbuild/win32-arm64': 0.20.0 - '@esbuild/win32-ia32': 0.20.0 - '@esbuild/win32-x64': 0.20.0 + '@esbuild/aix-ppc64': 0.20.1 + '@esbuild/android-arm': 0.20.1 + '@esbuild/android-arm64': 0.20.1 + '@esbuild/android-x64': 0.20.1 + '@esbuild/darwin-arm64': 0.20.1 + '@esbuild/darwin-x64': 0.20.1 + '@esbuild/freebsd-arm64': 0.20.1 + '@esbuild/freebsd-x64': 0.20.1 + '@esbuild/linux-arm': 0.20.1 + '@esbuild/linux-arm64': 0.20.1 + '@esbuild/linux-ia32': 0.20.1 + '@esbuild/linux-loong64': 0.20.1 + '@esbuild/linux-mips64el': 0.20.1 + '@esbuild/linux-ppc64': 0.20.1 + '@esbuild/linux-riscv64': 0.20.1 + '@esbuild/linux-s390x': 0.20.1 + '@esbuild/linux-x64': 0.20.1 + '@esbuild/netbsd-x64': 0.20.1 + '@esbuild/openbsd-x64': 0.20.1 + '@esbuild/sunos-x64': 0.20.1 + '@esbuild/win32-arm64': 0.20.1 + '@esbuild/win32-ia32': 0.20.1 + '@esbuild/win32-x64': 0.20.1 dev: true /escalade@3.1.1: @@ -6982,19 +6995,19 @@ packages: optionalDependencies: source-map: 0.6.1 - /eslint-plugin-vue@9.20.1(eslint@8.56.0): - resolution: {integrity: sha512-GyCs8K3lkEvoyC1VV97GJhP1SvqsKCiWGHnbn0gVUYiUhaH2+nB+Dv1uekv1THFMPbBfYxukrzQdltw950k+LQ==} + /eslint-plugin-vue@9.22.0(eslint@8.57.0): + resolution: {integrity: sha512-7wCXv5zuVnBtZE/74z4yZ0CM8AjH6bk4MQGm7hZjUC2DBppKU5ioeOk5LGSg/s9a1ZJnIsdPLJpXnu1Rc+cVHg==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) - eslint: 8.56.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + eslint: 8.57.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.0.15 semver: 7.6.0 - vue-eslint-parser: 9.4.2(eslint@8.56.0) + vue-eslint-parser: 9.4.2(eslint@8.57.0) xml-name-validator: 4.0.0 transitivePeerDependencies: - supports-color @@ -7012,15 +7025,15 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - /eslint@8.56.0: - resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} + /eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@eslint-community/regexpp': 4.6.2 '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.56.0 + '@eslint/js': 8.57.0 '@humanwhocodes/config-array': 0.11.14 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -7354,7 +7367,7 @@ packages: dev: false patched: true - /floating-vue@5.2.2(vue@3.4.19): + /floating-vue@5.2.2(vue@3.4.21): resolution: {integrity: sha512-afW+h2CFafo+7Y9Lvw/xsqjaQlKLdJV7h1fCHfcYQ1C4SVMlu7OAekqWgu5d4SgvkBVU0pVpLlVsrSTBURFRkg==} peerDependencies: '@nuxt/kit': ^3.2.0 @@ -7364,8 +7377,8 @@ packages: optional: true dependencies: '@floating-ui/dom': 1.1.1 - vue: 3.4.19(typescript@5.3.3) - vue-resize: 2.0.0-alpha.1(vue@3.4.19) + vue: 3.4.21(typescript@5.3.3) + vue-resize: 2.0.0-alpha.1(vue@3.4.21) dev: false /follow-redirects@1.15.4(debug@4.3.4): @@ -7649,8 +7662,8 @@ packages: strip-bom-string: 1.0.0 dev: true - /happy-dom@13.3.5: - resolution: {integrity: sha512-PBMhFNNBPGVa8oDP7mHv+kTWNtzIPTogS+V05s3ddsluDmTbcU7EaEMxZdYf2ka55MshloE9/opOHEC+YelzVQ==} + /happy-dom@13.6.2: + resolution: {integrity: sha512-Ku+wDqcF/KwFA0dI+xIMZd9Jn020RXjuSil/Vz7gu2yhDC3FsDYZ55qqV9k+SGC4opwb4acisXqVSRxUJMlPbQ==} engines: {node: '>=16.0.0'} dependencies: entities: 4.5.0 @@ -7717,16 +7730,16 @@ packages: engines: {node: '>=12.0.0'} dev: false - /histoire@0.17.9(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0)(vite@5.0.12): + /histoire@0.17.9(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0)(vite@5.1.4): resolution: {integrity: sha512-z5Jb9QwbOw0TKvpkU0v7+CxJG6hIljIKMhWXzOfteteRZGDFElpTEwbr5/8EdPI6VTdF/k76fqZ07nmS9YdUvA==} hasBin: true peerDependencies: vite: ^2.9.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 dependencies: '@akryum/tinypool': 0.3.1 - '@histoire/app': 0.17.9(vite@5.0.12) - '@histoire/controls': 0.17.9(vite@5.0.12) - '@histoire/shared': 0.17.9(vite@5.0.12) + '@histoire/app': 0.17.9(vite@5.1.4) + '@histoire/controls': 0.17.9(vite@5.1.4) + '@histoire/shared': 0.17.9(vite@5.1.4) '@histoire/vendors': 0.17.8 '@types/flexsearch': 0.7.6 '@types/markdown-it': 12.2.3 @@ -7753,8 +7766,8 @@ packages: sade: 1.8.1 shiki-es: 0.2.0 sirv: 2.0.3 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) - vite-node: 0.34.6(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vite-node: 0.34.6(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) transitivePeerDependencies: - '@types/node' - bufferutil @@ -8200,7 +8213,7 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.22 merge-stream: 2.0.0 supports-color: 7.2.0 dev: true @@ -8235,6 +8248,10 @@ packages: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true + /js-tokens@8.0.3: + resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==} + dev: true + /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -9243,7 +9260,7 @@ packages: engines: {node: '>=0.10.0'} dev: true - /pinia@2.1.7(typescript@5.3.3)(vue@3.4.19): + /pinia@2.1.7(typescript@5.3.3)(vue@3.4.21): resolution: {integrity: sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==} peerDependencies: '@vue/composition-api': ^1.4.0 @@ -9257,8 +9274,8 @@ packages: dependencies: '@vue/devtools-api': 6.5.0 typescript: 5.3.3 - vue: 3.4.19(typescript@5.3.3) - vue-demi: 0.14.6(vue@3.4.19) + vue: 3.4.21(typescript@5.3.3) + vue-demi: 0.14.6(vue@3.4.21) dev: false /pkg-dir@4.2.0: @@ -9275,27 +9292,27 @@ packages: mlly: 1.4.2 pathe: 1.1.1 - /postcss-attribute-case-insensitive@6.0.3(postcss@8.4.33): + /postcss-attribute-case-insensitive@6.0.3(postcss@8.4.35): resolution: {integrity: sha512-KHkmCILThWBRtg+Jn1owTnHPnFit4OkqS+eKiGEOPIGke54DCeYGJ6r0Fx/HjfE9M9kznApCLcU0DvnPchazMQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 - postcss-selector-parser: 6.0.15 + postcss: 8.4.35 + postcss-selector-parser: 6.0.13 dev: true - /postcss-clamp@4.1.0(postcss@8.4.33): + /postcss-clamp@4.1.0(postcss@8.4.35): resolution: {integrity: sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==} engines: {node: '>=7.6.0'} peerDependencies: postcss: ^8.4.6 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-color-functional-notation@6.0.5(postcss@8.4.33): + /postcss-color-functional-notation@6.0.5(postcss@8.4.35): resolution: {integrity: sha512-aTFsIy89ftjyclwUHRwvz1IxucLzVrzmmcXmtbPWT9GdyYeaJEKeAwbaZzOZn7AQlXg4xfwgkYhKsofC4aLIwg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -9304,34 +9321,34 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 dev: true - /postcss-color-hex-alpha@9.0.4(postcss@8.4.33): + /postcss-color-hex-alpha@9.0.4(postcss@8.4.35): resolution: {integrity: sha512-XQZm4q4fNFqVCYMGPiBjcqDhuG7Ey2xrl99AnDJMyr5eDASsAGalndVgHZF8i97VFNy1GQeZc4q2ydagGmhelQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-color-rebeccapurple@9.0.3(postcss@8.4.33): + /postcss-color-rebeccapurple@9.0.3(postcss@8.4.35): resolution: {integrity: sha512-ruBqzEFDYHrcVq3FnW3XHgwRqVMrtEPLBtD7K2YmsLKVc2jbkxzzNEctJKsPCpDZ+LeMHLKRDoSShVefGc+CkQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-custom-media@10.0.3(postcss@8.4.33): + /postcss-custom-media@10.0.3(postcss@8.4.35): resolution: {integrity: sha512-wfJ9nKpLn/Qy7LASKu0Rj9Iq2uMzlRt27P4FAE1889IKRMdYUgy8SqvdXfAOs7LJLQX9Fjm0mZ+TSFphD/mKwA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -9341,10 +9358,10 @@ packages: '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 '@csstools/media-query-list-parser': 2.1.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /postcss-custom-properties@13.3.5(postcss@8.4.33): + /postcss-custom-properties@13.3.5(postcss@8.4.35): resolution: {integrity: sha512-xHg8DTCMfN2nrqs2CQTF+0m5jgnzKL5zrW5Y05KF6xBRO0uDPxiplBm/xcr1o49SLbyJXkMuaRJKhRzkrquKnQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -9353,12 +9370,12 @@ packages: '@csstools/cascade-layer-name-parser': 1.0.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-custom-selectors@7.1.7(postcss@8.4.33): + /postcss-custom-selectors@7.1.7(postcss@8.4.35): resolution: {integrity: sha512-N19MpExaR+hYTXU59VO02xE42zLoAUYSVcupwkKlWWLteOb+sWCWHw5FhV7u7gVLTzaGULy7nZP3DNTHgOZAPA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -9367,29 +9384,29 @@ packages: '@csstools/cascade-layer-name-parser': 1.0.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - postcss: 8.4.33 - postcss-selector-parser: 6.0.15 + postcss: 8.4.35 + postcss-selector-parser: 6.0.13 dev: true - /postcss-dir-pseudo-class@8.0.1(postcss@8.4.33): + /postcss-dir-pseudo-class@8.0.1(postcss@8.4.35): resolution: {integrity: sha512-uULohfWBBVoFiZXgsQA24JV6FdKIidQ+ZqxOouhWwdE+qJlALbkS5ScB43ZTjPK+xUZZhlaO/NjfCt5h4IKUfw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 - postcss-selector-parser: 6.0.15 + postcss: 8.4.35 + postcss-selector-parser: 6.0.13 dev: true - /postcss-double-position-gradients@5.0.4(postcss@8.4.33): + /postcss-double-position-gradients@5.0.4(postcss@8.4.35): resolution: {integrity: sha512-xOH2QhazCPeYR+ziYaDcGlpo7Bpw8PVoggOFfU/xPkmBRUQH8MR2eWoPY1CZM93CB0WKs2mxq3ORo83QGIooLw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true @@ -9403,65 +9420,65 @@ packages: postcss-value-parser: 3.3.1 dev: true - /postcss-easings@4.0.0(postcss@8.4.33): + /postcss-easings@4.0.0(postcss@8.4.35): resolution: {integrity: sha512-KNpwHA3mTnf0UWcdwahQDaz7DDJ6QteVwdlLff98se854p6pyQW9iofwrD05vtlp33AAAxuUGCOhYwERRJGy6Q==} engines: {node: '>=16.0'} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-focus-visible@9.0.1(postcss@8.4.33): + /postcss-focus-visible@9.0.1(postcss@8.4.35): resolution: {integrity: sha512-N2VQ5uPz3Z9ZcqI5tmeholn4d+1H14fKXszpjogZIrFbhaq0zNAtq8sAnw6VLiqGbL8YBzsnu7K9bBkTqaRimQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 - postcss-selector-parser: 6.0.15 + postcss: 8.4.35 + postcss-selector-parser: 6.0.13 dev: true - /postcss-focus-within@8.0.1(postcss@8.4.33): + /postcss-focus-within@8.0.1(postcss@8.4.35): resolution: {integrity: sha512-NFU3xcY/xwNaapVb+1uJ4n23XImoC86JNwkY/uduytSl2s9Ekc2EpzmRR63+ExitnW3Mab3Fba/wRPCT5oDILA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-selector-parser: 6.0.13 dev: true - /postcss-font-variant@5.0.0(postcss@8.4.33): + /postcss-font-variant@5.0.0(postcss@8.4.35): resolution: {integrity: sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /postcss-gap-properties@5.0.1(postcss@8.4.33): + /postcss-gap-properties@5.0.1(postcss@8.4.35): resolution: {integrity: sha512-k2z9Cnngc24c0KF4MtMuDdToROYqGMMUQGcE6V0odwjHyOHtaDBlLeRBV70y9/vF7KIbShrTRZ70JjsI1BZyWw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /postcss-image-set-function@6.0.3(postcss@8.4.33): + /postcss-image-set-function@6.0.3(postcss@8.4.35): resolution: {integrity: sha512-i2bXrBYzfbRzFnm+pVuxVePSTCRiNmlfssGI4H0tJQvDue+yywXwUxe68VyzXs7cGtMaH6MCLY6IbCShrSroCw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-lab-function@6.0.10(postcss@8.4.33): + /postcss-lab-function@6.0.10(postcss@8.4.35): resolution: {integrity: sha512-Csvw/CwwuwTojK2O3Ad0SvYKrfnAKy+uvT+1Fjk6igR+n8gHuJHIwdj1A2s46EZZojg3RkibdMBuv1vMvR6Sng==} engines: {node: ^14 || ^16 || >=18} peerDependencies: @@ -9470,164 +9487,164 @@ packages: '@csstools/css-color-parser': 1.5.2(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) '@csstools/css-tokenizer': 2.2.3 - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) - '@csstools/utilities': 1.0.0(postcss@8.4.33) - postcss: 8.4.33 + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) + '@csstools/utilities': 1.0.0(postcss@8.4.35) + postcss: 8.4.35 dev: true - /postcss-logical@7.0.1(postcss@8.4.33): + /postcss-logical@7.0.1(postcss@8.4.35): resolution: {integrity: sha512-8GwUQZE0ri0K0HJHkDv87XOLC8DE0msc+HoWLeKdtjDZEwpZ5xuK3QdV6FhmHSQW40LPkg43QzvATRAI3LsRkg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-nesting@12.0.4(postcss@8.4.33): + /postcss-nesting@12.0.4(postcss@8.4.35): resolution: {integrity: sha512-WuCe0KnP4vKjLZK8VNoUWKL8ZLOv/5jiM94mHcI3VszLropHwmjotdUyP/ObzqZpXuQKP2Jf9R12vIHKFSStKw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.15) - postcss: 8.4.33 - postcss-selector-parser: 6.0.15 + '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.13) + postcss: 8.4.35 + postcss-selector-parser: 6.0.13 dev: true - /postcss-opacity-percentage@2.0.0(postcss@8.4.33): + /postcss-opacity-percentage@2.0.0(postcss@8.4.35): resolution: {integrity: sha512-lyDrCOtntq5Y1JZpBFzIWm2wG9kbEdujpNt4NLannF+J9c8CgFIzPa80YQfdza+Y+yFfzbYj/rfoOsYsooUWTQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.2 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /postcss-overflow-shorthand@5.0.1(postcss@8.4.33): + /postcss-overflow-shorthand@5.0.1(postcss@8.4.35): resolution: {integrity: sha512-XzjBYKLd1t6vHsaokMV9URBt2EwC9a7nDhpQpjoPk2HRTSQfokPfyAS/Q7AOrzUu6q+vp/GnrDBGuj/FCaRqrQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-page-break@3.0.4(postcss@8.4.33): + /postcss-page-break@3.0.4(postcss@8.4.35): resolution: {integrity: sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==} peerDependencies: postcss: ^8 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /postcss-place@9.0.1(postcss@8.4.33): + /postcss-place@9.0.1(postcss@8.4.35): resolution: {integrity: sha512-JfL+paQOgRQRMoYFc2f73pGuG/Aw3tt4vYMR6UA3cWVMxivviPTnMFnFTczUJOA4K2Zga6xgQVE+PcLs64WC8Q==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-preset-env@9.3.0(postcss@8.4.33): - resolution: {integrity: sha512-ycw6doPrqV6QxDCtgiyGDef61bEfiSc59HGM4gOw/wxQxmKnhuEery61oOC/5ViENz/ycpRsuhTexs1kUBTvVw==} + /postcss-preset-env@9.4.0(postcss@8.4.35): + resolution: {integrity: sha512-5X2UA4Dn4xo7sJFCxlzW/dAGo71Oxh/K5DVls33hd2e3j06OKnW5FJQTw2hB0wTnGv0f6WcMaVBGFqcEfAgwlw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/postcss-cascade-layers': 4.0.3(postcss@8.4.33) - '@csstools/postcss-color-function': 3.0.10(postcss@8.4.33) - '@csstools/postcss-color-mix-function': 2.0.10(postcss@8.4.33) - '@csstools/postcss-exponential-functions': 1.0.4(postcss@8.4.33) - '@csstools/postcss-font-format-keywords': 3.0.2(postcss@8.4.33) - '@csstools/postcss-gamut-mapping': 1.0.3(postcss@8.4.33) - '@csstools/postcss-gradients-interpolation-method': 4.0.11(postcss@8.4.33) - '@csstools/postcss-hwb-function': 3.0.9(postcss@8.4.33) - '@csstools/postcss-ic-unit': 3.0.4(postcss@8.4.33) - '@csstools/postcss-initial': 1.0.1(postcss@8.4.33) - '@csstools/postcss-is-pseudo-class': 4.0.5(postcss@8.4.33) - '@csstools/postcss-logical-float-and-clear': 2.0.1(postcss@8.4.33) - '@csstools/postcss-logical-overflow': 1.0.1(postcss@8.4.33) - '@csstools/postcss-logical-overscroll-behavior': 1.0.1(postcss@8.4.33) - '@csstools/postcss-logical-resize': 2.0.1(postcss@8.4.33) - '@csstools/postcss-logical-viewport-units': 2.0.6(postcss@8.4.33) - '@csstools/postcss-media-minmax': 1.1.3(postcss@8.4.33) - '@csstools/postcss-media-queries-aspect-ratio-number-values': 2.0.6(postcss@8.4.33) - '@csstools/postcss-nested-calc': 3.0.2(postcss@8.4.33) - '@csstools/postcss-normalize-display-values': 3.0.2(postcss@8.4.33) - '@csstools/postcss-oklab-function': 3.0.10(postcss@8.4.33) - '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.33) - '@csstools/postcss-relative-color-syntax': 2.0.10(postcss@8.4.33) - '@csstools/postcss-scope-pseudo-class': 3.0.1(postcss@8.4.33) - '@csstools/postcss-stepped-value-functions': 3.0.5(postcss@8.4.33) - '@csstools/postcss-text-decoration-shorthand': 3.0.4(postcss@8.4.33) - '@csstools/postcss-trigonometric-functions': 3.0.5(postcss@8.4.33) - '@csstools/postcss-unset-value': 3.0.1(postcss@8.4.33) - autoprefixer: 10.4.17(postcss@8.4.33) - browserslist: 4.22.3 - css-blank-pseudo: 6.0.1(postcss@8.4.33) - css-has-pseudo: 6.0.1(postcss@8.4.33) - css-prefers-color-scheme: 9.0.1(postcss@8.4.33) + '@csstools/postcss-cascade-layers': 4.0.3(postcss@8.4.35) + '@csstools/postcss-color-function': 3.0.10(postcss@8.4.35) + '@csstools/postcss-color-mix-function': 2.0.10(postcss@8.4.35) + '@csstools/postcss-exponential-functions': 1.0.4(postcss@8.4.35) + '@csstools/postcss-font-format-keywords': 3.0.2(postcss@8.4.35) + '@csstools/postcss-gamut-mapping': 1.0.3(postcss@8.4.35) + '@csstools/postcss-gradients-interpolation-method': 4.0.11(postcss@8.4.35) + '@csstools/postcss-hwb-function': 3.0.9(postcss@8.4.35) + '@csstools/postcss-ic-unit': 3.0.4(postcss@8.4.35) + '@csstools/postcss-initial': 1.0.1(postcss@8.4.35) + '@csstools/postcss-is-pseudo-class': 4.0.5(postcss@8.4.35) + '@csstools/postcss-light-dark-function': 1.0.0(postcss@8.4.35) + '@csstools/postcss-logical-float-and-clear': 2.0.1(postcss@8.4.35) + '@csstools/postcss-logical-overflow': 1.0.1(postcss@8.4.35) + '@csstools/postcss-logical-overscroll-behavior': 1.0.1(postcss@8.4.35) + '@csstools/postcss-logical-resize': 2.0.1(postcss@8.4.35) + '@csstools/postcss-logical-viewport-units': 2.0.6(postcss@8.4.35) + '@csstools/postcss-media-minmax': 1.1.3(postcss@8.4.35) + '@csstools/postcss-media-queries-aspect-ratio-number-values': 2.0.6(postcss@8.4.35) + '@csstools/postcss-nested-calc': 3.0.2(postcss@8.4.35) + '@csstools/postcss-normalize-display-values': 3.0.2(postcss@8.4.35) + '@csstools/postcss-oklab-function': 3.0.10(postcss@8.4.35) + '@csstools/postcss-progressive-custom-properties': 3.1.0(postcss@8.4.35) + '@csstools/postcss-relative-color-syntax': 2.0.10(postcss@8.4.35) + '@csstools/postcss-scope-pseudo-class': 3.0.1(postcss@8.4.35) + '@csstools/postcss-stepped-value-functions': 3.0.5(postcss@8.4.35) + '@csstools/postcss-text-decoration-shorthand': 3.0.4(postcss@8.4.35) + '@csstools/postcss-trigonometric-functions': 3.0.5(postcss@8.4.35) + '@csstools/postcss-unset-value': 3.0.1(postcss@8.4.35) + autoprefixer: 10.4.17(postcss@8.4.35) + browserslist: 4.23.0 + css-blank-pseudo: 6.0.1(postcss@8.4.35) + css-has-pseudo: 6.0.2(postcss@8.4.35) + css-prefers-color-scheme: 9.0.1(postcss@8.4.35) cssdb: 7.11.1 - postcss: 8.4.33 - postcss-attribute-case-insensitive: 6.0.3(postcss@8.4.33) - postcss-clamp: 4.1.0(postcss@8.4.33) - postcss-color-functional-notation: 6.0.5(postcss@8.4.33) - postcss-color-hex-alpha: 9.0.4(postcss@8.4.33) - postcss-color-rebeccapurple: 9.0.3(postcss@8.4.33) - postcss-custom-media: 10.0.3(postcss@8.4.33) - postcss-custom-properties: 13.3.5(postcss@8.4.33) - postcss-custom-selectors: 7.1.7(postcss@8.4.33) - postcss-dir-pseudo-class: 8.0.1(postcss@8.4.33) - postcss-double-position-gradients: 5.0.4(postcss@8.4.33) - postcss-focus-visible: 9.0.1(postcss@8.4.33) - postcss-focus-within: 8.0.1(postcss@8.4.33) - postcss-font-variant: 5.0.0(postcss@8.4.33) - postcss-gap-properties: 5.0.1(postcss@8.4.33) - postcss-image-set-function: 6.0.3(postcss@8.4.33) - postcss-lab-function: 6.0.10(postcss@8.4.33) - postcss-logical: 7.0.1(postcss@8.4.33) - postcss-nesting: 12.0.4(postcss@8.4.33) - postcss-opacity-percentage: 2.0.0(postcss@8.4.33) - postcss-overflow-shorthand: 5.0.1(postcss@8.4.33) - postcss-page-break: 3.0.4(postcss@8.4.33) - postcss-place: 9.0.1(postcss@8.4.33) - postcss-pseudo-class-any-link: 9.0.1(postcss@8.4.33) - postcss-replace-overflow-wrap: 4.0.0(postcss@8.4.33) - postcss-selector-not: 7.0.2(postcss@8.4.33) - postcss-value-parser: 4.2.0 + postcss: 8.4.35 + postcss-attribute-case-insensitive: 6.0.3(postcss@8.4.35) + postcss-clamp: 4.1.0(postcss@8.4.35) + postcss-color-functional-notation: 6.0.5(postcss@8.4.35) + postcss-color-hex-alpha: 9.0.4(postcss@8.4.35) + postcss-color-rebeccapurple: 9.0.3(postcss@8.4.35) + postcss-custom-media: 10.0.3(postcss@8.4.35) + postcss-custom-properties: 13.3.5(postcss@8.4.35) + postcss-custom-selectors: 7.1.7(postcss@8.4.35) + postcss-dir-pseudo-class: 8.0.1(postcss@8.4.35) + postcss-double-position-gradients: 5.0.4(postcss@8.4.35) + postcss-focus-visible: 9.0.1(postcss@8.4.35) + postcss-focus-within: 8.0.1(postcss@8.4.35) + postcss-font-variant: 5.0.0(postcss@8.4.35) + postcss-gap-properties: 5.0.1(postcss@8.4.35) + postcss-image-set-function: 6.0.3(postcss@8.4.35) + postcss-lab-function: 6.0.10(postcss@8.4.35) + postcss-logical: 7.0.1(postcss@8.4.35) + postcss-nesting: 12.0.4(postcss@8.4.35) + postcss-opacity-percentage: 2.0.0(postcss@8.4.35) + postcss-overflow-shorthand: 5.0.1(postcss@8.4.35) + postcss-page-break: 3.0.4(postcss@8.4.35) + postcss-place: 9.0.1(postcss@8.4.35) + postcss-pseudo-class-any-link: 9.0.1(postcss@8.4.35) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.4.35) + postcss-selector-not: 7.0.2(postcss@8.4.35) dev: true - /postcss-pseudo-class-any-link@9.0.1(postcss@8.4.33): + /postcss-pseudo-class-any-link@9.0.1(postcss@8.4.35): resolution: {integrity: sha512-cKYGGZ9yzUZi+dZd7XT2M8iSDfo+T2Ctbpiizf89uBTBfIpZpjvTavzIJXpCReMVXSKROqzpxClNu6fz4DHM0Q==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 - postcss-selector-parser: 6.0.15 + postcss: 8.4.35 + postcss-selector-parser: 6.0.13 dev: true - /postcss-replace-overflow-wrap@4.0.0(postcss@8.4.33): + /postcss-replace-overflow-wrap@4.0.0(postcss@8.4.35): resolution: {integrity: sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==} peerDependencies: postcss: ^8.0.3 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /postcss-selector-not@7.0.2(postcss@8.4.33): + /postcss-selector-not@7.0.2(postcss@8.4.35): resolution: {integrity: sha512-/SSxf/90Obye49VZIfc0ls4H0P6i6V1iHv0pzZH8SdgvZOPFkF37ef1r5cyWcMflJSFJ5bfuoluTnFnBBFiuSA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - postcss: 8.4.33 - postcss-selector-parser: 6.0.15 + postcss: 8.4.35 + postcss-selector-parser: 6.0.13 dev: true /postcss-selector-parser@6.0.13: @@ -9662,8 +9679,8 @@ packages: source-map: 0.6.1 dev: true - /postcss@8.4.33: - resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + /postcss@8.4.35: + resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.7 @@ -10157,7 +10174,7 @@ packages: - acorn dev: true - /rollup-plugin-visualizer@5.12.0(rollup@4.9.6): + /rollup-plugin-visualizer@5.12.0(rollup@4.12.0): resolution: {integrity: sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==} engines: {node: '>=14'} hasBin: true @@ -10169,7 +10186,7 @@ packages: dependencies: open: 8.4.0 picomatch: 2.3.1 - rollup: 4.9.6 + rollup: 4.12.0 source-map: 0.7.4 yargs: 17.6.0 dev: true @@ -10182,26 +10199,26 @@ packages: fsevents: 2.3.3 dev: true - /rollup@4.9.6: - resolution: {integrity: sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==} + /rollup@4.12.0: + resolution: {integrity: sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.9.6 - '@rollup/rollup-android-arm64': 4.9.6 - '@rollup/rollup-darwin-arm64': 4.9.6 - '@rollup/rollup-darwin-x64': 4.9.6 - '@rollup/rollup-linux-arm-gnueabihf': 4.9.6 - '@rollup/rollup-linux-arm64-gnu': 4.9.6 - '@rollup/rollup-linux-arm64-musl': 4.9.6 - '@rollup/rollup-linux-riscv64-gnu': 4.9.6 - '@rollup/rollup-linux-x64-gnu': 4.9.6 - '@rollup/rollup-linux-x64-musl': 4.9.6 - '@rollup/rollup-win32-arm64-msvc': 4.9.6 - '@rollup/rollup-win32-ia32-msvc': 4.9.6 - '@rollup/rollup-win32-x64-msvc': 4.9.6 + '@rollup/rollup-android-arm-eabi': 4.12.0 + '@rollup/rollup-android-arm64': 4.12.0 + '@rollup/rollup-darwin-arm64': 4.12.0 + '@rollup/rollup-darwin-x64': 4.12.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.12.0 + '@rollup/rollup-linux-arm64-gnu': 4.12.0 + '@rollup/rollup-linux-arm64-musl': 4.12.0 + '@rollup/rollup-linux-riscv64-gnu': 4.12.0 + '@rollup/rollup-linux-x64-gnu': 4.12.0 + '@rollup/rollup-linux-x64-musl': 4.12.0 + '@rollup/rollup-win32-arm64-msvc': 4.12.0 + '@rollup/rollup-win32-ia32-msvc': 4.12.0 + '@rollup/rollup-win32-x64-msvc': 4.12.0 fsevents: 2.3.3 /rope-sequence@1.3.4: @@ -10246,8 +10263,8 @@ packages: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} dev: true - /sass@1.70.0: - resolution: {integrity: sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==} + /sass@1.71.1: + resolution: {integrity: sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==} engines: {node: '>=14.0.0'} hasBin: true dependencies: @@ -10621,10 +10638,10 @@ packages: engines: {node: '>=8'} dev: true - /strip-literal@1.3.0: - resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + /strip-literal@2.0.0: + resolution: {integrity: sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==} dependencies: - acorn: 8.11.2 + js-tokens: 8.0.3 dev: true /style-mod@4.1.0: @@ -11042,13 +11059,13 @@ packages: engines: {node: '>=4'} dev: true - /update-browserslist-db@1.0.13(browserslist@4.22.3): + /update-browserslist-db@1.0.13(browserslist@4.23.0): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.22.3 + browserslist: 4.23.0 escalade: 3.1.1 picocolors: 1.0.0 dev: true @@ -11134,7 +11151,7 @@ packages: extsprintf: 1.3.0 dev: true - /vite-node@0.34.6(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0): + /vite-node@0.34.6(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0): resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} engines: {node: '>=v14.18.0'} hasBin: true @@ -11144,7 +11161,7 @@ packages: mlly: 1.4.2 pathe: 1.1.1 picocolors: 1.0.0 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) transitivePeerDependencies: - '@types/node' - less @@ -11156,8 +11173,8 @@ packages: - terser dev: true - /vite-node@1.2.2(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0): - resolution: {integrity: sha512-1as4rDTgVWJO3n1uHmUYqq7nsFgINQ9u+mRcXpjeOMJUmviqNKjcZB7UfRZrlM7MjYXMKpuWp5oGkjaFLnjawg==} + /vite-node@1.3.1(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0): + resolution: {integrity: sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true dependencies: @@ -11165,7 +11182,7 @@ packages: debug: 4.3.4(supports-color@8.1.1) pathe: 1.1.1 picocolors: 1.0.0 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) transitivePeerDependencies: - '@types/node' - less @@ -11177,58 +11194,62 @@ packages: - terser dev: true - /vite-plugin-inject-preload@1.3.3(vite@5.0.12): + /vite-plugin-inject-preload@1.3.3(vite@5.1.4): resolution: {integrity: sha512-nh5+6BZdR/iFZj6pfDR8NHxQgRELkcmM5f9ufj9X6BWXgh3x6SWNp24TfiYvhwQyOV/vrVXpo0DqNBSgppmeOQ==} engines: {node: '>=14.18.0'} peerDependencies: vite: ^3.0.0 || ^4.0.0 dependencies: mime-types: 2.1.35 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) dev: true - /vite-plugin-pwa@0.17.5(vite@5.0.12)(workbox-build@7.0.0)(workbox-window@7.0.0): - resolution: {integrity: sha512-UxRNPiJBzh4tqU/vc8G2TxmrUTzT6BqvSzhszLk62uKsf+npXdvLxGDz9C675f4BJi6MbD2tPnJhi5txlMzxbQ==} + /vite-plugin-pwa@0.19.1(vite@5.1.4)(workbox-build@7.0.0)(workbox-window@7.0.0): + resolution: {integrity: sha512-pxubJSqDfiUflmFfU8ErPP2eIHz7SqiSuJz6Qk2dPlEeC5Wm2hTInYhmVBYVx1KbVUEhQ4f8uCdmhYB/YP/pqw==} engines: {node: '>=16.0.0'} peerDependencies: + '@vite-pwa/assets-generator': ^0.2.4 vite: ^3.1.0 || ^4.0.0 || ^5.0.0 workbox-build: ^7.0.0 workbox-window: ^7.0.0 + peerDependenciesMeta: + '@vite-pwa/assets-generator': + optional: true dependencies: debug: 4.3.4(supports-color@8.1.1) fast-glob: 3.3.2 pretty-bytes: 6.1.1 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) workbox-build: 7.0.0(acorn@8.11.2) workbox-window: 7.0.0 transitivePeerDependencies: - supports-color dev: true - /vite-plugin-sentry@1.3.0(vite@5.0.12): - resolution: {integrity: sha512-cei2ocb0l9hOuij8//DPMFl2Fcl0gVOBWGbqZ7F3aNLHUFkZvGm+B+aTWPX9CDpwW0uLcqqoo8O9rckFF0PGLA==} + /vite-plugin-sentry@1.4.0(vite@5.1.4): + resolution: {integrity: sha512-Jt9AeDnh9XLjEA1pAfU0NW0jCyJE8lAXMJWZKc+SoIxZRKSY64fitDOg9Ta1G98LhPaiDKL6dhVeROUmjY/aUQ==} engines: {node: '>= 14'} peerDependencies: - vite: ^2.6.0 || ^3.0.0 || ^4.0.0 + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 dependencies: '@sentry/cli': 2.19.1 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) transitivePeerDependencies: - encoding - supports-color dev: true - /vite-svg-loader@5.1.0(vue@3.4.19): + /vite-svg-loader@5.1.0(vue@3.4.21): resolution: {integrity: sha512-M/wqwtOEjgb956/+m5ZrYT/Iq6Hax0OakWbokj8+9PXOnB7b/4AxESHieEtnNEy7ZpjsjYW1/5nK8fATQMmRxw==} peerDependencies: vue: '>=3.2.13' dependencies: svgo: 3.0.2 - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) dev: true - /vite@5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0): - resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==} + /vite@5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0): + resolution: {integrity: sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -11255,25 +11276,25 @@ packages: terser: optional: true dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.22 esbuild: 0.19.12 - postcss: 8.4.33 - rollup: 4.9.6 - sass: 1.70.0 + postcss: 8.4.35 + rollup: 4.12.0 + sass: 1.71.1 terser: 5.24.0 optionalDependencies: fsevents: 2.3.3 dev: true - /vitest@1.2.2(@types/node@20.11.10)(happy-dom@13.3.5)(sass@1.70.0)(terser@5.24.0): - resolution: {integrity: sha512-d5Ouvrnms3GD9USIK36KG8OZ5bEvKEkITFtnGv56HFaSlbItJuYr7hv2Lkn903+AvRAgSixiamozUVfORUekjw==} + /vitest@1.3.1(@types/node@20.11.22)(happy-dom@13.6.2)(sass@1.71.1)(terser@5.24.0): + resolution: {integrity: sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': ^1.0.0 - '@vitest/ui': ^1.0.0 + '@vitest/browser': 1.3.1 + '@vitest/ui': 1.3.1 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -11290,28 +11311,27 @@ packages: jsdom: optional: true dependencies: - '@types/node': 20.11.10 - '@vitest/expect': 1.2.2 - '@vitest/runner': 1.2.2 - '@vitest/snapshot': 1.2.2 - '@vitest/spy': 1.2.2 - '@vitest/utils': 1.2.2 + '@types/node': 20.11.22 + '@vitest/expect': 1.3.1 + '@vitest/runner': 1.3.1 + '@vitest/snapshot': 1.3.1 + '@vitest/spy': 1.3.1 + '@vitest/utils': 1.3.1 acorn-walk: 8.3.2 - cac: 6.7.14 chai: 4.3.10 debug: 4.3.4(supports-color@8.1.1) execa: 8.0.1 - happy-dom: 13.3.5 + happy-dom: 13.6.2 local-pkg: 0.5.0 magic-string: 0.30.7 pathe: 1.1.1 picocolors: 1.0.0 std-env: 3.6.0 - strip-literal: 1.3.0 + strip-literal: 2.0.0 tinybench: 2.5.1 tinypool: 0.8.2 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) - vite-node: 1.2.2(@types/node@20.11.10)(sass@1.70.0)(terser@5.24.0) + vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) + vite-node: 1.3.1(@types/node@20.11.22)(sass@1.71.1)(terser@5.24.0) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -11323,7 +11343,7 @@ packages: - terser dev: true - /vue-advanced-cropper@2.8.8(vue@3.4.19): + /vue-advanced-cropper@2.8.8(vue@3.4.21): resolution: {integrity: sha512-yDM7Jb/gnxcs//JdbOogBUoHr1bhCQSto7/ohgETKAe4wvRpmqIkKSppMm1huVQr+GP1YoVlX/fkjKxvYzwwDQ==} engines: {node: '>=8', npm: '>=5'} peerDependencies: @@ -11332,14 +11352,14 @@ packages: classnames: 2.3.1 debounce: 1.2.1 easy-bem: 1.1.1 - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) dev: false /vue-component-type-helpers@1.8.22: resolution: {integrity: sha512-LK3wJHs3vJxHG292C8cnsRusgyC5SEZDCzDCD01mdE/AoREFMl2tzLRuzwyuEsOIz13tqgBcnvysN3Lxsa14Fw==} dev: true - /vue-demi@0.14.6(vue@3.4.19): + /vue-demi@0.14.6(vue@3.4.21): resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} engines: {node: '>=12'} hasBin: true @@ -11351,10 +11371,10 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) dev: false - /vue-demi@0.14.7(vue@3.4.19): + /vue-demi@0.14.7(vue@3.4.21): resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==} engines: {node: '>=12'} hasBin: true @@ -11366,35 +11386,35 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) dev: false - /vue-eslint-parser@9.3.1(eslint@8.56.0): + /vue-eslint-parser@9.3.1(eslint@8.57.0): resolution: {integrity: sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' dependencies: debug: 4.3.4(supports-color@8.1.1) - eslint: 8.56.0 + eslint: 8.57.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 esquery: 1.4.2 lodash: 4.17.21 - semver: 7.6.0 + semver: 7.5.4 transitivePeerDependencies: - supports-color dev: true - /vue-eslint-parser@9.4.2(eslint@8.56.0): + /vue-eslint-parser@9.4.2(eslint@8.57.0): resolution: {integrity: sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' dependencies: debug: 4.3.4(supports-color@8.1.1) - eslint: 8.56.0 + eslint: 8.57.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 @@ -11405,17 +11425,17 @@ packages: - supports-color dev: true - /vue-flatpickr-component@11.0.4(vue@3.4.19): + /vue-flatpickr-component@11.0.4(vue@3.4.21): resolution: {integrity: sha512-rhYYCfKpPHMaqTYy/jUlzg2HOlmvSMtEUJ7uB5R1gZZfxyarE5h80WAO/vtbCxxgS030KcZywIQjZG4tIgW4xg==} engines: {node: '>=14.13.0'} peerDependencies: vue: ^3.2.0 dependencies: flatpickr: 4.6.13 - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) dev: false - /vue-i18n@9.9.1(vue@3.4.19): + /vue-i18n@9.9.1(vue@3.4.21): resolution: {integrity: sha512-xyQ4VspLdNSPTKBFBPWa1tvtj+9HuockZwgFeD2OhxxXuC2CWeNvV4seu2o9+vbQOyQbhAM5Ez56oxUrrnTWdw==} engines: {node: '>= 16'} peerDependencies: @@ -11424,24 +11444,24 @@ packages: '@intlify/core-base': 9.9.1 '@intlify/shared': 9.9.1 '@vue/devtools-api': 6.5.0 - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) dev: false - /vue-resize@2.0.0-alpha.1(vue@3.4.19): + /vue-resize@2.0.0-alpha.1(vue@3.4.21): resolution: {integrity: sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==} peerDependencies: vue: ^3.0.0 dependencies: - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) dev: false - /vue-router@4.3.0(vue@3.4.19): + /vue-router@4.3.0(vue@3.4.21): resolution: {integrity: sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ==} peerDependencies: vue: ^3.2.0 dependencies: '@vue/devtools-api': 6.6.1 - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) dev: false /vue-template-compiler@2.7.14: @@ -11463,19 +11483,19 @@ packages: typescript: 5.3.3 dev: true - /vue@3.4.19(typescript@5.3.3): - resolution: {integrity: sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==} + /vue@3.4.21(typescript@5.3.3): + resolution: {integrity: sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@vue/compiler-dom': 3.4.19 - '@vue/compiler-sfc': 3.4.19 - '@vue/runtime-dom': 3.4.19 - '@vue/server-renderer': 3.4.19(vue@3.4.19) - '@vue/shared': 3.4.19 + '@vue/compiler-dom': 3.4.21 + '@vue/compiler-sfc': 3.4.21 + '@vue/runtime-dom': 3.4.21 + '@vue/server-renderer': 3.4.21(vue@3.4.21) + '@vue/shared': 3.4.21 typescript: 5.3.3 /w3c-keyname@2.2.6: @@ -11915,13 +11935,13 @@ packages: engines: {node: '>=12.20'} dev: true - /zhyswan-vuedraggable@4.1.3(vue@3.4.19): + /zhyswan-vuedraggable@4.1.3(vue@3.4.21): resolution: {integrity: sha512-q4Mp52tQIvTAWG0CKxLCVLyG/3RnIskDxoJvfjDZ2kM8yTcMkY80VTc8rd3q9KwqJ0UVtjEGLufb23sjDp0peQ==} peerDependencies: vue: ^3.0.1 dependencies: sortablejs: 1.14.0 - vue: 3.4.19(typescript@5.3.3) + vue: 3.4.21(typescript@5.3.3) dev: false /zod@3.22.4: -- 2.45.1