Compare commits

..

1 commit

Author SHA1 Message Date
0d348e2398 chore(deps): update dependency svelte to v5
Some checks failed
continuous-integration/drone/push Build is failing
2025-01-18 10:47:54 +00:00
58 changed files with 1000 additions and 1612 deletions

View file

@ -20,7 +20,7 @@ RUN go get -d -v ./admin && \
go build -v -buildmode=plugin -o repochecker/videos-rules.so ./repochecker/videos go build -v -buildmode=plugin -o repochecker/videos-rules.so ./repochecker/videos
FROM alpine:3.21 FROM alpine:3.20
RUN apk add --no-cache \ RUN apk add --no-cache \
ca-certificates \ ca-certificates \

View file

@ -13,7 +13,7 @@ RUN go get -d -v ./checker && \
go build -v -buildvcs=false -o checker/checker ./checker go build -v -buildvcs=false -o checker/checker ./checker
FROM alpine:3.21 FROM alpine:3.20
WORKDIR /srv WORKDIR /srv

View file

@ -13,7 +13,7 @@ RUN go get -d -v ./dashboard && \
go build -v -buildvcs=false -o dashboard/dashboard ./dashboard go build -v -buildvcs=false -o dashboard/dashboard ./dashboard
FROM alpine:3.21 FROM alpine:3.20
EXPOSE 8082 EXPOSE 8082

View file

@ -1,4 +1,4 @@
FROM alpine:3.21 FROM alpine:3.20
EXPOSE 67/udp EXPOSE 67/udp
EXPOSE 69/udp EXPOSE 69/udp

View file

@ -12,7 +12,7 @@ RUN go get -d -v ./evdist && \
go build -v -buildvcs=false -o evdist/evdist ./evdist go build -v -buildvcs=false -o evdist/evdist ./evdist
FROM alpine:3.21 FROM alpine:3.20
WORKDIR /srv WORKDIR /srv

View file

@ -13,7 +13,7 @@ RUN go get -d -v ./generator && \
go build -v -buildvcs=false -o generator/generator ./generator go build -v -buildvcs=false -o generator/generator ./generator
FROM alpine:3.21 FROM alpine:3.20
WORKDIR /srv WORKDIR /srv

View file

@ -15,7 +15,7 @@ RUN go get -d -v ./admin && \
go build -v -o get-remote-files ./admin/get-remote-files go build -v -o get-remote-files ./admin/get-remote-files
FROM alpine:3.21 FROM alpine:3.20
RUN apk add --no-cache \ RUN apk add --no-cache \
ca-certificates ca-certificates

View file

@ -25,7 +25,7 @@ RUN go get -d -v ./qa && \
go build -v -buildvcs=false -o qa/qa ./qa go build -v -buildvcs=false -o qa/qa ./qa
FROM alpine:3.21 FROM alpine:3.20
EXPOSE 8083 EXPOSE 8083

View file

@ -13,7 +13,7 @@ RUN go get -d -v ./receiver && \
go build -v -buildvcs=false -o ./receiver/receiver ./receiver go build -v -buildvcs=false -o ./receiver/receiver ./receiver
FROM alpine:3.21 FROM alpine:3.20
EXPOSE 8080 EXPOSE 8080

View file

@ -13,7 +13,7 @@ RUN go get -d -v ./remote/challenge-sync-airbus && \
go build -v -buildvcs=false -o ./challenge-sync-airbus ./remote/challenge-sync-airbus go build -v -buildvcs=false -o ./challenge-sync-airbus ./remote/challenge-sync-airbus
FROM alpine:3.21 FROM alpine:3.20
RUN apk add --no-cache openssl ca-certificates RUN apk add --no-cache openssl ca-certificates

View file

@ -13,7 +13,7 @@ RUN go get -d -v ./remote/scores-sync-zqds && \
go build -v -buildvcs=false -o ./scores-sync-zqds ./remote/scores-sync-zqds go build -v -buildvcs=false -o ./scores-sync-zqds ./remote/scores-sync-zqds
FROM alpine:3.21 FROM alpine:3.20
RUN apk add --no-cache openssl ca-certificates RUN apk add --no-cache openssl ca-certificates

View file

@ -62,8 +62,6 @@ func declareExercicesRoutes(router *gin.RouterGroup) {
apiFlagsRoutes.POST("/try", tryExerciceFlag) apiFlagsRoutes.POST("/try", tryExerciceFlag)
apiFlagsRoutes.DELETE("/", deleteExerciceFlag) apiFlagsRoutes.DELETE("/", deleteExerciceFlag)
apiFlagsRoutes.GET("/dependancies", showExerciceFlagDeps) apiFlagsRoutes.GET("/dependancies", showExerciceFlagDeps)
apiFlagsRoutes.GET("/statistics", showExerciceFlagStats)
apiFlagsRoutes.DELETE("/tries", deleteExerciceFlagTries)
apiFlagsRoutes.GET("/choices/", listFlagChoices) apiFlagsRoutes.GET("/choices/", listFlagChoices)
apiFlagsChoicesRoutes := apiExercicesRoutes.Group("/choices/:cid") apiFlagsChoicesRoutes := apiExercicesRoutes.Group("/choices/:cid")
apiFlagsChoicesRoutes.Use(FlagChoiceHandler) apiFlagsChoicesRoutes.Use(FlagChoiceHandler)
@ -79,8 +77,6 @@ func declareExercicesRoutes(router *gin.RouterGroup) {
apiQuizRoutes.PUT("", updateExerciceQuiz) apiQuizRoutes.PUT("", updateExerciceQuiz)
apiQuizRoutes.DELETE("", deleteExerciceQuiz) apiQuizRoutes.DELETE("", deleteExerciceQuiz)
apiQuizRoutes.GET("/dependancies", showExerciceQuizDeps) apiQuizRoutes.GET("/dependancies", showExerciceQuizDeps)
apiQuizRoutes.GET("/statistics", showExerciceQuizStats)
apiQuizRoutes.DELETE("/tries", deleteExerciceQuizTries)
apiExercicesRoutes.GET("/tags", listExerciceTags) apiExercicesRoutes.GET("/tags", listExerciceTags)
apiExercicesRoutes.POST("/tags", addExerciceTag) apiExercicesRoutes.POST("/tags", addExerciceTag)
@ -856,60 +852,6 @@ func showExerciceFlagDeps(c *gin.Context) {
c.JSON(http.StatusOK, deps) c.JSON(http.StatusOK, deps)
} }
func showExerciceFlagStats(c *gin.Context) {
exercice := c.MustGet("exercice").(*fic.Exercice)
flag := c.MustGet("flag-key").(*fic.FlagKey)
history, err := exercice.GetHistory()
if err != nil {
log.Println("Unable to getExerciceHistory:", err.Error())
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving exercice history"})
return
}
var completed int64
for _, hline := range history {
if hline["kind"].(string) == "flag_found" {
if *hline["secondary"].(*int) == flag.Id {
completed += 1
}
}
}
tries, err := flag.NbTries()
if err != nil {
log.Println("Unable to nbTries:", err.Error())
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving flag tries"})
return
}
teams, err := flag.TeamsOnIt()
if err != nil {
log.Println("Unable to teamsOnIt:", err.Error())
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving flag related teams"})
return
}
c.JSON(http.StatusOK, gin.H{
"completed": completed,
"tries": tries,
"teams": teams,
})
}
func deleteExerciceFlagTries(c *gin.Context) {
flag := c.MustGet("flag-key").(*fic.FlagKey)
err := flag.DeleteTries()
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
return
}
c.AbortWithStatusJSON(http.StatusOK, true)
}
func tryExerciceFlag(c *gin.Context) { func tryExerciceFlag(c *gin.Context) {
flag := c.MustGet("flag-key").(*fic.FlagKey) flag := c.MustGet("flag-key").(*fic.FlagKey)
@ -953,23 +895,6 @@ func updateExerciceFlag(c *gin.Context) {
flag.Help = uk.Help flag.Help = uk.Help
flag.IgnoreCase = uk.IgnoreCase flag.IgnoreCase = uk.IgnoreCase
flag.Multiline = uk.Multiline flag.Multiline = uk.Multiline
flag.ChoicesCost = uk.ChoicesCost
flag.BonusGain = uk.BonusGain
if uk.CaptureRe != nil && len(*uk.CaptureRe) > 0 {
if flag.CaptureRegexp != uk.CaptureRe && uk.Flag == "" {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Pour changer la capture_regexp, vous devez rentrer la réponse attendue à nouveau, car le flag doit être recalculé."})
return
}
flag.CaptureRegexp = uk.CaptureRe
} else {
if flag.CaptureRegexp != nil && uk.Flag == "" {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Pour changer la capture_regexp, vous devez rentrer la réponse attendue à nouveau, car le flag doit être recalculé."})
return
}
flag.CaptureRegexp = nil
}
if len(uk.Flag) > 0 { if len(uk.Flag) > 0 {
var err error var err error
flag.Checksum, err = flag.ComputeChecksum([]byte(uk.Flag)) flag.Checksum, err = flag.ComputeChecksum([]byte(uk.Flag))
@ -981,6 +906,14 @@ func updateExerciceFlag(c *gin.Context) {
} else { } else {
flag.Checksum = uk.Value flag.Checksum = uk.Value
} }
flag.ChoicesCost = uk.ChoicesCost
flag.BonusGain = uk.BonusGain
if uk.CaptureRe != nil && len(*uk.CaptureRe) > 0 {
flag.CaptureRegexp = uk.CaptureRe
} else {
flag.CaptureRegexp = nil
}
if _, err := flag.Update(); err != nil { if _, err := flag.Update(); err != nil {
log.Println("Unable to updateExerciceFlag:", err.Error()) log.Println("Unable to updateExerciceFlag:", err.Error())
@ -1089,60 +1022,6 @@ func showExerciceQuizDeps(c *gin.Context) {
c.JSON(http.StatusOK, deps) c.JSON(http.StatusOK, deps)
} }
func showExerciceQuizStats(c *gin.Context) {
exercice := c.MustGet("exercice").(*fic.Exercice)
quiz := c.MustGet("flag-quiz").(*fic.MCQ)
history, err := exercice.GetHistory()
if err != nil {
log.Println("Unable to getExerciceHistory:", err.Error())
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving exercice history"})
return
}
var completed int64
for _, hline := range history {
if hline["kind"].(string) == "mcq_found" {
if *hline["secondary"].(*int) == quiz.Id {
completed += 1
}
}
}
tries, err := quiz.NbTries()
if err != nil {
log.Println("Unable to nbTries:", err.Error())
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving flag tries"})
return
}
teams, err := quiz.TeamsOnIt()
if err != nil {
log.Println("Unable to teamsOnIt:", err.Error())
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving flag related teams"})
return
}
c.JSON(http.StatusOK, gin.H{
"completed": completed,
"tries": tries,
"teams": teams,
})
}
func deleteExerciceQuizTries(c *gin.Context) {
quiz := c.MustGet("flag-quiz").(*fic.MCQ)
err := quiz.DeleteTries()
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
return
}
c.AbortWithStatusJSON(http.StatusOK, true)
}
func updateExerciceQuiz(c *gin.Context) { func updateExerciceQuiz(c *gin.Context) {
quiz := c.MustGet("flag-quiz").(*fic.MCQ) quiz := c.MustGet("flag-quiz").(*fic.MCQ)

View file

@ -3,12 +3,9 @@ package api
import ( import (
"archive/zip" "archive/zip"
"encoding/json" "encoding/json"
"io"
"log"
"net/http" "net/http"
"path" "path"
"srs.epita.fr/fic-server/admin/sync"
"srs.epita.fr/fic-server/libfic" "srs.epita.fr/fic-server/libfic"
"srs.epita.fr/fic-server/settings" "srs.epita.fr/fic-server/settings"
@ -62,41 +59,6 @@ func declareExportRoutes(router *gin.RouterGroup) {
json.NewEncoder(f).Encode(challengeinfo) json.NewEncoder(f).Encode(challengeinfo)
} }
// Include partners' logos from challenge.json
if sync.GlobalImporter != nil {
if len(challengeinfo.MainLogo) > 0 {
for _, logo := range challengeinfo.MainLogo {
fd, closer, err := sync.OpenOrGetFile(sync.GlobalImporter, logo)
if err != nil {
log.Printf("Unable to archive main logo %q: %s", logo, err.Error())
continue
}
f, err := w.Create(path.Join("logo", path.Base(logo)))
if err == nil {
io.Copy(f, fd)
}
closer()
}
}
if len(challengeinfo.Partners) > 0 {
for _, partner := range challengeinfo.Partners {
fd, closer, err := sync.OpenOrGetFile(sync.GlobalImporter, partner.Src)
if err != nil {
log.Printf("Unable to archive partner logo %q: %s", partner.Src, err.Error())
continue
}
f, err := w.Create(path.Join("partner", path.Base(partner.Src)))
if err == nil {
io.Copy(f, fd)
}
closer()
}
}
}
// my.json // my.json
f, err = w.Create("my.json") f, err = w.Create("my.json")
if err == nil { if err == nil {

View file

@ -34,11 +34,6 @@ func declarePasswordRoutes(router *gin.RouterGroup) {
c.JSON(http.StatusOK, gin.H{"password": passwd}) c.JSON(http.StatusOK, gin.H{"password": passwd})
}) })
router.GET("/oauth-status", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"secret_defined": OidcSecret != "",
})
})
router.GET("/dex.yaml", func(c *gin.Context) { router.GET("/dex.yaml", func(c *gin.Context) {
cfg, err := genDexConfig() cfg, err := genDexConfig()
if err != nil { if err != nil {
@ -141,7 +136,7 @@ storage:
web: web:
http: 0.0.0.0:5556 http: 0.0.0.0:5556
frontend: frontend:
issuer: {{ .Name }} issuer: Challenge forensic
logoURL: {{ .LogoPath }} logoURL: {{ .LogoPath }}
dir: /srv/dex/web/ dir: /srv/dex/web/
oauth2: oauth2:

View file

@ -1,9 +1,9 @@
package api package api
import ( import (
"encoding/json"
"fmt" "fmt"
"log" "log"
"math/rand"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
@ -186,9 +186,6 @@ func declareTeamsRoutes(router *gin.RouterGroup) {
declareTeamsPasswordRoutes(apiTeamsRoutes) declareTeamsPasswordRoutes(apiTeamsRoutes)
declareTeamClaimsRoutes(apiTeamsRoutes) declareTeamClaimsRoutes(apiTeamsRoutes)
declareTeamCertificateRoutes(apiTeamsRoutes) declareTeamCertificateRoutes(apiTeamsRoutes)
// Import teams from cyberrange
router.POST("/cyberrange-teams.json", importTeamsFromCyberrange)
} }
func TeamHandler(c *gin.Context) { func TeamHandler(c *gin.Context) {
@ -295,11 +292,6 @@ func bindingTeams(c *gin.Context) {
c.String(http.StatusOK, ret) c.String(http.StatusOK, ret)
} }
type teamAssociation struct {
Association string `json:"association"`
TeamId int64 `json:"team_id"`
}
func allAssociations(c *gin.Context) { func allAssociations(c *gin.Context) {
teams, err := fic.GetTeams() teams, err := fic.GetTeams()
if err != nil { if err != nil {
@ -308,7 +300,7 @@ func allAssociations(c *gin.Context) {
return return
} }
var ret []teamAssociation var ret []string
for _, team := range teams { for _, team := range teams {
assocs, err := pki.GetTeamAssociations(TeamsDir, team.Id) assocs, err := pki.GetTeamAssociations(TeamsDir, team.Id)
@ -318,84 +310,13 @@ func allAssociations(c *gin.Context) {
} }
for _, a := range assocs { for _, a := range assocs {
ret = append(ret, teamAssociation{a, team.Id}) ret = append(ret, a)
} }
} }
c.JSON(http.StatusOK, ret) c.JSON(http.StatusOK, ret)
} }
func importTeamsFromCyberrange(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"errmsg": "Failed to get file: " + err.Error()})
return
}
src, err := file.Open()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"errmsg": "Failed to open file: " + err.Error()})
return
}
defer src.Close()
var ut []fic.CyberrangeTeam
err = json.NewDecoder(src).Decode(&fic.CyberrangeAPIResponse{Data: &ut})
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
return
}
teams, err := fic.GetTeams()
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Impossible de récupérer la liste des équipes actuelles: %s", err.Error())})
return
}
for _, crteam := range ut {
var exist_team *fic.Team
for _, team := range teams {
if team.Name == crteam.Name && team.ExternalId == crteam.UUID {
exist_team = team
break
}
}
if exist_team != nil {
exist_team.Name = crteam.Name
exist_team.ExternalId = crteam.UUID
_, err = exist_team.Update()
} else {
exist_team, err = fic.CreateTeam(crteam.Name, fic.RandomColor().ToRGB(), crteam.UUID)
}
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Impossible d'ajouter/de modifier l'équipe %v: %s", crteam, err.Error())})
return
}
// Import members
if c.DefaultQuery("nomembers", "0") != "" && len(crteam.Members) > 0 {
exist_team.ClearMembers()
for _, member := range crteam.Members {
_, err = exist_team.AddMember(member.Name, "", member.Nickname, exist_team.Name)
if err != nil {
log.Printf("Unable to add member %q to team %s (tid=%d): %s", member.UUID, exist_team.Name, exist_team.Id, err.Error())
}
}
}
}
teams, err = fic.GetTeams()
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Impossible de récupérer la liste des équipes après import: %s", err.Error())})
return
}
c.JSON(http.StatusOK, teams)
}
func createTeam(c *gin.Context) { func createTeam(c *gin.Context) {
var ut fic.Team var ut fic.Team
err := c.ShouldBindJSON(&ut) err := c.ShouldBindJSON(&ut)
@ -405,7 +326,11 @@ func createTeam(c *gin.Context) {
} }
if ut.Color == 0 { if ut.Color == 0 {
ut.Color = fic.RandomColor().ToRGB() ut.Color = fic.HSL{
H: rand.Float64(),
S: 1,
L: 0.5,
}.ToRGB()
} }
team, err := fic.CreateTeam(strings.TrimSpace(ut.Name), ut.Color, ut.ExternalId) team, err := fic.CreateTeam(strings.TrimSpace(ut.Name), ut.Color, ut.ExternalId)

View file

@ -4,7 +4,7 @@ const indextpl = `<!DOCTYPE html>
<html ng-app="FICApp"> <html ng-app="FICApp">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>{{ .title }} - Administration</title> <title>Challenge Forensic - Administration</title>
<link href="{{.urlbase}}css/bootstrap.min.css" type="text/css" rel="stylesheet"> <link href="{{.urlbase}}css/bootstrap.min.css" type="text/css" rel="stylesheet">
<link href="{{.urlbase}}css/glyphicon.css" type="text/css" rel="stylesheet" media="screen"> <link href="{{.urlbase}}css/glyphicon.css" type="text/css" rel="stylesheet" media="screen">
<style> <style>
@ -86,7 +86,7 @@ const indextpl = `<!DOCTYPE html>
<body class="bg-light text-dark"> <body class="bg-light text-dark">
<nav class="navbar sticky-top navbar-expand-lg navbar-dark text-light" ng-class="{'bg-dark': settings.wip, 'bg-danger': !settings.wip}"> <nav class="navbar sticky-top navbar-expand-lg navbar-dark text-light" ng-class="{'bg-dark': settings.wip, 'bg-danger': !settings.wip}">
<a class="navbar-brand" href="."> <a class="navbar-brand" href=".">
<img alt="{{ .title }}" src="{{ .logo }}" style="height: 30px"> <img alt="FIC" src="img/fic.png" style="height: 30px">
</a> </a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#adminMenu" aria-controls="adminMenu" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#adminMenu" aria-controls="adminMenu" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
@ -95,7 +95,7 @@ const indextpl = `<!DOCTYPE html>
<div class="collapse navbar-collapse" id="adminMenu"> <div class="collapse navbar-collapse" id="adminMenu">
<ul class="navbar-nav mr-auto"> <ul class="navbar-nav mr-auto">
<li class="nav-item" ng-class="{'active': $location.path().startsWith('/teams')}"><a class="nav-link" href="teams">&Eacute;quipes</a></li> <li class="nav-item" ng-class="{'active': $location.path().startsWith('/teams')}"><a class="nav-link" href="teams">&Eacute;quipes</a></li>
<li class="nav-item" ng-class="{'active': $location.path().startsWith('/auth')}"><a class="nav-link" href="auth">Authentification</a></li> <li class="nav-item" ng-class="{'active': $location.path().startsWith('/pki')}"><a class="nav-link" href="pki">PKI</a></li>
<li class="nav-item" ng-class="{'active': $location.path().startsWith('/themes')}"><a class="nav-link" href="themes">Thèmes</a></li> <li class="nav-item" ng-class="{'active': $location.path().startsWith('/themes')}"><a class="nav-link" href="themes">Thèmes</a></li>
<li class="nav-item" ng-class="{'active': $location.path().startsWith('/exercices')}"><a class="nav-link" href="exercices">Exercices</a></li> <li class="nav-item" ng-class="{'active': $location.path().startsWith('/exercices')}"><a class="nav-link" href="exercices">Exercices</a></li>
<li class="nav-item" ng-class="{'active': $location.path().startsWith('/public')}"><a class="nav-link" href="public/0">Public</a></li> <li class="nav-item" ng-class="{'active': $location.path().startsWith('/public')}"><a class="nav-link" href="public/0">Public</a></li>
@ -124,7 +124,7 @@ const indextpl = `<!DOCTYPE html>
</div> </div>
<span id="clock" class="navbar-text" ng-controller="CountdownController" ng-cloak> <span id="clock" class="navbar-text" ng-controller="CountdownController" ng-cloak>
<div style="pointer-events: none; position: absolute;"> <div style="position: absolute;">
<div style="position: absolute;" id="circle1" class="circle-anim border-danger"></div> <div style="position: absolute;" id="circle1" class="circle-anim border-danger"></div>
<div style="position: absolute;" id="circle2" class="circle-anim border-info"></div> <div style="position: absolute;" id="circle2" class="circle-anim border-info"></div>
</div> </div>

View file

@ -6,7 +6,6 @@ import (
"errors" "errors"
"log" "log"
"net/http" "net/http"
"os"
"path" "path"
"strings" "strings"
"text/template" "text/template"
@ -26,24 +25,10 @@ var assets embed.FS
var indexPage []byte var indexPage []byte
func genIndex(baseURL string) { func genIndex(baseURL string) {
tplcfg := map[string]string{
"logo": "img/logo.png",
"title": "Challenge",
"urlbase": path.Clean(path.Join(baseURL+"/", "nuke"))[:len(path.Clean(path.Join(baseURL+"/", "nuke")))-4],
}
ci, err := api.GetChallengeInfo()
if err == nil && ci != nil {
tplcfg["title"] = ci.Title
if len(ci.MainLogo) > 0 {
tplcfg["logo"] = "/files/logo/" + path.Base(ci.MainLogo[0])
}
}
b := bytes.NewBufferString("") b := bytes.NewBufferString("")
if indexTmpl, err := template.New("index").Parse(indextpl); err != nil { if indexTmpl, err := template.New("index").Parse(indextpl); err != nil {
log.Fatal("Cannot create template:", err) log.Fatal("Cannot create template:", err)
} else if err = indexTmpl.Execute(b, tplcfg); err != nil { } else if err = indexTmpl.Execute(b, map[string]string{"urlbase": path.Clean(path.Join(baseURL+"/", "nuke"))[:len(path.Clean(path.Join(baseURL+"/", "nuke")))-4]}); err != nil {
log.Fatal("An error occurs during template execution:", err) log.Fatal("An error occurs during template execution:", err)
} else { } else {
indexPage = b.Bytes() indexPage = b.Bytes()
@ -65,9 +50,6 @@ func declareStaticRoutes(router *gin.RouterGroup, cfg *settings.Settings, baseUR
router.GET("/", func(c *gin.Context) { router.GET("/", func(c *gin.Context) {
serveIndex(c) serveIndex(c)
}) })
router.GET("/auth/*_", func(c *gin.Context) {
serveIndex(c)
})
router.GET("/claims/*_", func(c *gin.Context) { router.GET("/claims/*_", func(c *gin.Context) {
serveIndex(c) serveIndex(c)
}) })
@ -122,22 +104,8 @@ func declareStaticRoutes(router *gin.RouterGroup, cfg *settings.Settings, baseUR
}) })
router.GET("/files/*_", func(c *gin.Context) { router.GET("/files/*_", func(c *gin.Context) {
filepath := path.Join(fic.FilesDir, strings.TrimPrefix(strings.TrimPrefix(c.Request.URL.Path, baseURL), "/files")) // TODO: handle .gz file here
http.ServeFile(c.Writer, c.Request, path.Join(fic.FilesDir, strings.TrimPrefix(c.Request.URL.Path, path.Join(baseURL, "files"))))
if st, err := os.Stat(filepath); os.IsNotExist(err) || st.Size() == 0 {
if st, err := os.Stat(filepath + ".gz"); err == nil {
if fd, err := os.Open(filepath + ".gz"); err == nil {
log.Println(filepath + ".gz")
c.DataFromReader(http.StatusOK, st.Size(), "application/octet-stream", fd, map[string]string{
"Content-Encoding": "gzip",
})
return
}
}
}
log.Println(filepath)
c.File(filepath)
}) })
router.GET("/submissions/*_", func(c *gin.Context) { router.GET("/submissions/*_", func(c *gin.Context) {
http.ServeFile(c.Writer, c.Request, path.Join(api.TimestampCheck, strings.TrimPrefix(c.Request.URL.Path, path.Join(baseURL, "submissions")))) http.ServeFile(c.Writer, c.Request, path.Join(api.TimestampCheck, strings.TrimPrefix(c.Request.URL.Path, path.Join(baseURL, "submissions"))))

View file

@ -25,10 +25,6 @@ angular.module("FICApp", ["ngRoute", "ngResource", "ngSanitize"])
controller: "SettingsController", controller: "SettingsController",
templateUrl: "views/settings.html" templateUrl: "views/settings.html"
}) })
.when("/auth", {
controller: "AuthController",
templateUrl: "views/auth.html"
})
.when("/pki", { .when("/pki", {
controller: "PKIController", controller: "PKIController",
templateUrl: "views/pki.html" templateUrl: "views/pki.html"
@ -352,9 +348,6 @@ angular.module("FICApp")
.factory("ExerciceFlagDeps", function ($resource) { .factory("ExerciceFlagDeps", function ($resource) {
return $resource("api/exercices/:exerciceId/flags/:flagId/dependancies", { exerciceId: '@idExercice', flagId: '@id' }) return $resource("api/exercices/:exerciceId/flags/:flagId/dependancies", { exerciceId: '@idExercice', flagId: '@id' })
}) })
.factory("ExerciceFlagStats", function ($resource) {
return $resource("api/exercices/:exerciceId/flags/:flagId/statistics", { exerciceId: '@idExercice', flagId: '@id' })
})
.factory("ExerciceMCQFlag", function ($resource) { .factory("ExerciceMCQFlag", function ($resource) {
return $resource("api/exercices/:exerciceId/quiz/:mcqId", { exerciceId: '@idExercice', mcqId: '@id' }, { return $resource("api/exercices/:exerciceId/quiz/:mcqId", { exerciceId: '@idExercice', mcqId: '@id' }, {
update: { method: 'PUT' } update: { method: 'PUT' }
@ -362,9 +355,6 @@ angular.module("FICApp")
}) })
.factory("ExerciceMCQDeps", function ($resource) { .factory("ExerciceMCQDeps", function ($resource) {
return $resource("api/exercices/:exerciceId/quiz/:mcqId/dependancies", { exerciceId: '@idExercice', mcqId: '@id' }) return $resource("api/exercices/:exerciceId/quiz/:mcqId/dependancies", { exerciceId: '@idExercice', mcqId: '@id' })
})
.factory("ExerciceMCQStats", function ($resource) {
return $resource("api/exercices/:exerciceId/quiz/:mcqId/statistics", { exerciceId: '@idExercice', mcqId: '@id' })
}); });
angular.module("FICApp") angular.module("FICApp")
@ -621,18 +611,9 @@ angular.module("FICApp")
response.enableExerciceDepend = response.unlockedChallengeDepth >= 0; response.enableExerciceDepend = response.unlockedChallengeDepth >= 0;
response.disabledsubmitbutton = response.disablesubmitbutton && response.disablesubmitbutton.length > 0; response.disabledsubmitbutton = response.disablesubmitbutton && response.disablesubmitbutton.length > 0;
if (response.end) {
$scope.duration = (response.end - response.start)/60000;
}
}) })
$scope.challenge = SettingsChallenge.get(); $scope.challenge = SettingsChallenge.get();
$scope.duration = 360; $scope.duration = 360;
$scope.durationChange = function(endChanged) {
if (endChanged)
$scope.duration = (new Date($scope.config.end).getTime() - new Date($scope.config.start).getTime())/60000;
else
$scope.config.end = new Date(new Date($scope.config.start).getTime() + $scope.duration * 60000);
}
$scope.activateTime = ""; $scope.activateTime = "";
$scope.challenge.$promise.then(function (c) { $scope.challenge.$promise.then(function (c) {
if (c.duration) if (c.duration)
@ -667,7 +648,7 @@ angular.module("FICApp")
$scope.saveChallengeInfo = function () { $scope.saveChallengeInfo = function () {
this.challenge.duration = $scope.duration; this.challenge.duration = $scope.duration;
this.challenge.$update(function (response) { this.challenge.$update(function (response) {
$scope.addToast('success', 'Infos du challenge mises à jour avec succès!'); $scope.addToast('success', 'Infos du challenge mises à jour avec succès !');
}, function (response) { }, function (response) {
$scope.addToast('danger', 'An error occurs when saving challenge info:', response.data.errmsg); $scope.addToast('danger', 'An error occurs when saving challenge info:', response.data.errmsg);
}); });
@ -741,9 +722,9 @@ angular.module("FICApp")
"teams": "En validant, vous supprimerez l'ensemble des équipes enregistreées.", "teams": "En validant, vous supprimerez l'ensemble des équipes enregistreées.",
"game": "En validant, vous supprimerez toutes les tentatives, les validations, ... faites par les équipes.", "game": "En validant, vous supprimerez toutes les tentatives, les validations, ... faites par les équipes.",
} }
$scope.addToast('warning', txts[type], 'Êtes-vous sûr de vouloir continuer?', $scope.addToast('warning', txts[type], 'Êtes-vous sûr de vouloir continuer ?',
function () { function () {
if (confirm("Êtes-vous vraiment sûr?\n" + txts[type])) { if (confirm("Êtes-vous vraiment sûr ?\n" + txts[type])) {
$http.post("api/reset", { "type": type }).then(function (time) { $http.post("api/reset", { "type": type }).then(function (time) {
$scope.addToast('success', type + 'reseted'); $scope.addToast('success', type + 'reseted');
$location.url("/"); $location.url("/");
@ -755,7 +736,7 @@ angular.module("FICApp")
}); });
}; };
$scope.switchToProd = function () { $scope.switchToProd = function () {
$scope.addToast('warning', "Activer le mode challenge?", "L'activation du mode challenge est temporaire (vous devriez plutôt relancer le daemon avec l'option `-4real`). Ce mode permet d'éviter les mauvaises manipulations et désactive le hook git de synchronisation automatique. Êtes-vous sûr de vouloir continuer?", $scope.addToast('warning', "Activer le mode challenge ?", "L'activation du mode challenge est temporaire (vous devriez plutôt relancer le daemon avec l'option `-4real`). Ce mode permet d'éviter les mauvaises manipulations et désactive le hook git de synchronisation automatique. Êtes-vous sûr de vouloir continuer ?",
function () { function () {
$http.put("api/prod", true).then(function (time) { $http.put("api/prod", true).then(function (time) {
$rootScope.refreshSettings() $rootScope.refreshSettings()
@ -778,20 +759,6 @@ angular.module("FICApp")
}); });
}; };
}) })
.component('teamLink', {
bindings: {
idTeam: '=',
},
controller: function (Team) {
var ctrl = this;
ctrl.team = {};
ctrl.$onInit = function () {
ctrl.team = Team.get({teamId: ctrl.idTeam});
};
},
template: `<a href="/teams/{{ $ctrl.idTeam }}">{{ $ctrl.team.name }}</a> `
})
.component('repositoryUptodate', { .component('repositoryUptodate', {
bindings: { bindings: {
repository: '<', repository: '<',
@ -853,10 +820,10 @@ angular.module("FICApp")
$scope.deepSync = function (theme) { $scope.deepSync = function (theme) {
if (theme) { if (theme) {
question = 'Faire une synchronisation intégrale du thème ' + theme.name + '?' question = 'Faire une synchronisation intégrale du thème ' + theme.name + ' ?'
url = "api/sync/deep/" + theme.id url = "api/sync/deep/" + theme.id
} else { } else {
question = 'Faire une synchronisation intégrale?' question = 'Faire une synchronisation intégrale ?'
url = "api/sync/deep" url = "api/sync/deep"
} }
$scope.addToast('warning', question, '', $scope.addToast('warning', question, '',
@ -872,7 +839,7 @@ angular.module("FICApp")
}); });
}; };
$scope.speedyDeepSync = function () { $scope.speedyDeepSync = function () {
$scope.addToast('warning', 'Faire une synchronisation profonde rapide, sans s\'occuper des fichiers?', '', $scope.addToast('warning', 'Faire une synchronisation profonde rapide, sans s\'occuper des fichiers ?', '',
function () { function () {
$scope.deepSyncInProgress = true; $scope.deepSyncInProgress = true;
$http.post("api/sync/speed").then(function () { $http.post("api/sync/speed").then(function () {
@ -885,7 +852,7 @@ angular.module("FICApp")
}); });
}; };
$scope.baseSync = function () { $scope.baseSync = function () {
$scope.addToast('warning', 'Tirer les mises à jour du dépôt?', '', $scope.addToast('warning', 'Tirer les mises à jour du dépôt ?', '',
function () { function () {
$scope.deepSyncInProgress = true; $scope.deepSyncInProgress = true;
$http.post("api/sync/base").then(function () { $http.post("api/sync/base").then(function () {
@ -898,7 +865,7 @@ angular.module("FICApp")
}); });
}; };
$scope.syncVideos = function () { $scope.syncVideos = function () {
$scope.addToast('warning', 'Synchroniser les vidéos de résolution?', 'ATTENTION il ne faut pas lancer cette synchronisation durant le challenge. Seulement une fois le challenge terminé, cela permet de rendre les vidéos accessibles dans l\'interface joueurs.', $scope.addToast('warning', 'Synchroniser les vidéos de résolution ?', 'ATTENTION il ne faut pas lancer cette synchronisation durant le challenge. Seulement une fois le challenge terminé, cela permet de rendre les vidéos accessibles dans l\'interface joueurs.',
function () { function () {
$scope.deepSyncInProgress = true; $scope.deepSyncInProgress = true;
$http.post("api/sync/videos").then(function () { $http.post("api/sync/videos").then(function () {
@ -925,49 +892,6 @@ angular.module("FICApp")
}; };
}) })
.controller("AuthController", function ($scope, $http) {
$scope.generateHtpasswd = function () {
$http.post("api/htpasswd").then(function () {
$scope.addToast('success', 'Fichier htpasswd généré avec succès');
}, function (response) {
$scope.addToast('danger', 'An error occurs when generating htpasswd file:', response.data.errmsg);
});
};
$scope.removeHtpasswd = function () {
$http.delete("api/htpasswd").then(function () {
$scope.addToast('success', 'Fichier htpasswd supprimé avec succès');
}, function (response) {
$scope.addToast('danger', 'An error occurs when deleting htpasswd file:', response.data.errmsg);
});
};
})
.controller("OAuthController", function ($scope, $http) {
$scope.refreshOAuthStatus = function () {
$http.get("api/oauth-status").then(function (res) {
$scope.oauth_status = response.data;
});
};
$scope.genDexCfg = function () {
$http.post("api/dex.yaml").then(function () {
$http.post("api/dex-password.tpl").then(function () {
$scope.addToast('success', 'Dex config refreshed.', "Don't forget to reload/reboot frontend host.");
}, function (response) {
$scope.addToast('danger', 'An error occurs when generating dex password tpl:', response.data.errmsg);
});
}, function (response) {
$scope.addToast('danger', 'An error occurs when generating dex config:', response.data.errmsg);
});
$http.post("api/vouch-proxy.yaml").then(function () {
$scope.addToast('success', 'VouchProxy config refreshed.', "Don't forget to reload/reboot frontend host.");
}, function (response) {
$scope.addToast('danger', 'An error occurs when generating VouchProxy config:', response.data.errmsg);
});
}
})
.controller("PKIController", function ($scope, $rootScope, Certificate, CACertificate, Team, $location, $http) { .controller("PKIController", function ($scope, $rootScope, Certificate, CACertificate, Team, $location, $http) {
var ts = Date.now() - Date.now() % 86400000; var ts = Date.now() - Date.now() % 86400000;
var d = new Date(ts); var d = new Date(ts);
@ -1052,6 +976,20 @@ angular.module("FICApp")
$scope.addToast('danger', 'An error occurs when generating certificate:', response.data.errmsg); $scope.addToast('danger', 'An error occurs when generating certificate:', response.data.errmsg);
}); });
}; };
$scope.generateHtpasswd = function () {
$http.post("api/htpasswd").then(function () {
$scope.addToast('success', 'Fichier htpasswd généré avec succès');
}, function (response) {
$scope.addToast('danger', 'An error occurs when generating htpasswd file:', response.data.errmsg);
});
};
$scope.removeHtpasswd = function () {
$http.delete("api/htpasswd").then(function () {
$scope.addToast('success', 'Fichier htpasswd supprimé avec succès');
}, function (response) {
$scope.addToast('danger', 'An error occurs when deleting htpasswd file:', response.data.errmsg);
});
};
}) })
.controller("PublicController", function ($scope, $rootScope, $routeParams, $location, Scene, Theme, Teams, Exercice) { .controller("PublicController", function ($scope, $rootScope, $routeParams, $location, Scene, Theme, Teams, Exercice) {
@ -1172,7 +1110,7 @@ angular.module("FICApp")
}, },
{ {
type: "countdown", type: "countdown",
params: { color: "success", end: null, lead: "Go, go, go!", title: "Le challenge forensic va bientôt commencer!" }, params: { color: "success", end: null, lead: "Go, go, go !", title: "Le challenge forensic va bientôt commencer !" },
}, },
]; ];
$scope.display.side = [ $scope.display.side = [
@ -1291,8 +1229,8 @@ angular.module("FICApp")
show: true, show: true,
shadow: "#E8CF5C", shadow: "#E8CF5C",
end: new Date($rootScope.getSrvTime().getTime() + 1802000).toISOString(), end: new Date($rootScope.getSrvTime().getTime() + 1802000).toISOString(),
before: "Heure joyeuse: chaque résolution compte double!", before: "Heure joyeuse : chaque résolution compte double !",
after: "Heure joyeuse terminée!", after: "Heure joyeuse terminée !",
} }
} }
else if (scene == "freehintquarter") { else if (scene == "freehintquarter") {
@ -1300,8 +1238,8 @@ angular.module("FICApp")
show: true, show: true,
shadow: "#3DD28F", shadow: "#3DD28F",
end: new Date($rootScope.getSrvTime().getTime() + 902000).toISOString(), end: new Date($rootScope.getSrvTime().getTime() + 902000).toISOString(),
before: "Quart d'heure facile: indices dévoilés!", before: "Quart d'heure facile : indices dévoilés !",
after: "Quart d'heure facile terminée!", after: "Quart d'heure facile terminée !",
} }
} }
}; };
@ -1430,7 +1368,7 @@ angular.module("FICApp")
}); });
}; };
$scope.clearFilesDir = function () { $scope.clearFilesDir = function () {
$scope.addToast('warning', 'Êtes-vous sûr de vouloir continuer?', "Ceci va supprimer tout le contenu du dossier FILES. Il s'agit des fichiers ci-dessous, il faudra refaire une synchronisation ensuite.", $scope.addToast('warning', 'Êtes-vous sûr de vouloir continuer ?', "Ceci va supprimer tout le contenu du dossier FILES. Il s'agit des fichiers ci-dessous, il faudra refaire une synchronisation ensuite.",
function () { function () {
$scope.clearFilesWIP = true; $scope.clearFilesWIP = true;
$http({ $http({
@ -2317,9 +2255,9 @@ angular.module("FICApp")
} }
$scope.saveFlag = function () { $scope.saveFlag = function () {
if (this.flag.id) { if (this.flag.id) {
this.flag.$update().then(function() {}, function(error) { $scope.addToast('danger', 'Impossible de mettre à jour le flag :', error.data.errmsg); }); this.flag.$update();
} else { } else {
this.flag.$save({ exerciceId: $routeParams.exerciceId }).then(function() {}, function(error) { $scope.addToast('danger', 'Impossible de créer le flag :', error.data.errmsg); }); this.flag.$save({ exerciceId: $routeParams.exerciceId });
} }
$rootScope.staticFilesNeedUpdate++; $rootScope.staticFilesNeedUpdate++;
} }
@ -2338,7 +2276,7 @@ angular.module("FICApp")
method: "POST" method: "POST"
}).then(function (response) { }).then(function (response) {
flag.test_str = ""; flag.test_str = "";
$scope.addToast('success', "Flag Ok!"); $scope.addToast('success', "Flag Ok !");
}, function (response) { }, function (response) {
flag.test_str = ""; flag.test_str = "";
$scope.addToast('danger', 'An error occurs: ', response.data.errmsg); $scope.addToast('danger', 'An error occurs: ', response.data.errmsg);
@ -2407,18 +2345,6 @@ angular.module("FICApp")
} }
}) })
.controller("ExerciceFlagStatsController", function ($scope, $routeParams, ExerciceFlagStats, $http) {
$scope.init = function (flag) {
$scope.flag_id = flag.id;
$scope.stats = ExerciceFlagStats.get({ exerciceId: $routeParams.exerciceId, flagId: flag.id });
}
$scope.deleteTries = function () {
$http.delete(`/api/exercices/${$routeParams.exerciceId}/flags/${$scope.flag_id}/tries`).then(function () {
$scope.stats = ExerciceFlagStats.get({ exerciceId: $routeParams.exerciceId, flagId: $scope.flag_id });
});
}
})
.controller("ExerciceMCQFlagsController", function ($scope, ExerciceMCQFlag, $routeParams, $rootScope) { .controller("ExerciceMCQFlagsController", function ($scope, ExerciceMCQFlag, $routeParams, $rootScope) {
$scope.quiz = ExerciceMCQFlag.query({ exerciceId: $routeParams.exerciceId }); $scope.quiz = ExerciceMCQFlag.query({ exerciceId: $routeParams.exerciceId });
@ -2456,18 +2382,6 @@ angular.module("FICApp")
} }
}) })
.controller("ExerciceMCQStatsController", function ($scope, $routeParams, ExerciceMCQStats, $http) {
$scope.init = function (mcq) {
$scope.mcq_id = mcq.id;
$scope.stats = ExerciceMCQStats.get({ exerciceId: $routeParams.exerciceId, mcqId: mcq.id });
}
$scope.deleteTries = function () {
$http.delete(`/api/exercices/${$routeParams.exerciceId}/quiz/${$scope.mcq_id}/tries`).then(function () {
$scope.stats = ExerciceMCQStats.get({ exerciceId: $routeParams.exerciceId, mcqId: $scope.mcq_id });
});
}
})
.controller("TeamsListController", function ($scope, $rootScope, Team, $location, $http) { .controller("TeamsListController", function ($scope, $rootScope, Team, $location, $http) {
$scope.teams = Team.query(); $scope.teams = Team.query();
$scope.fields = ["id", "name"]; $scope.fields = ["id", "name"];
@ -2494,6 +2408,22 @@ angular.module("FICApp")
} }
}; };
$scope.genDexCfg = function () {
$http.post("api/dex.yaml").then(function () {
$http.post("api/dex-password.tpl").then(function () {
$scope.addToast('success', 'Dex config refreshed.', "Don't forget to reload/reboot frontend host.");
}, function (response) {
$scope.addToast('danger', 'An error occurs when generating dex password tpl:', response.data.errmsg);
});
}, function (response) {
$scope.addToast('danger', 'An error occurs when generating dex config:', response.data.errmsg);
});
$http.post("api/vouch-proxy.yaml").then(function () {
$scope.addToast('success', 'VouchProxy config refreshed.', "Don't forget to reload/reboot frontend host.");
}, function (response) {
$scope.addToast('danger', 'An error occurs when generating VouchProxy config:', response.data.errmsg);
});
}
$scope.desactiveTeams = function () { $scope.desactiveTeams = function () {
$http.post("api/disableinactiveteams").then(function () { $http.post("api/disableinactiveteams").then(function () {
$scope.teams = Team.query(); $scope.teams = Team.query();
@ -2501,34 +2431,9 @@ angular.module("FICApp")
$scope.addToast('danger', 'An error occurs when disabling inactive teams:', response.data.errmsg); $scope.addToast('danger', 'An error occurs when disabling inactive teams:', response.data.errmsg);
}); });
} }
$scope.refineTeamsColors = function () {
$http.post("api/refine_colors").then(function () {
$scope.teams = Team.query();
}, function (response) {
$scope.addToast('danger', 'An error occurs when updating teams:', response.data.errmsg);
});
}
$scope.show = function (id) { $scope.show = function (id) {
$location.url("/teams/" + id); $location.url("/teams/" + id);
}; };
$scope.triggerTeamsImport = function() {
document.getElementById('crTeamsInput').click();
};
$scope.uploadFile = function() {
var formData = new FormData();
formData.append('file', $scope.selectedFile);
$http.post('api/cyberrange-teams.json', formData, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined},
}).then(function(response) {
$scope.teams = response.data;
$scope.addToast('success', 'Import des équipes', "L'import a été réalisé avec succès !");
}, function(error) {
console.log(error);
$scope.addToast('danger', 'Import des équipes', error.data.errmsg);
});
};
}) })
.controller("TeamMembersController", function ($scope, TeamMember) { .controller("TeamMembersController", function ($scope, TeamMember) {
$scope.fields = ["firstname", "lastname", "nickname", "company"]; $scope.fields = ["firstname", "lastname", "nickname", "company"];

View file

@ -81,22 +81,6 @@ angular.module("FICApp")
}); });
} }
} }
}])
.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function($scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
$scope.$apply(function(){
modelSetter($scope, element[0].files[0]);
$scope.uploadFile();
});
});
}
};
}]); }]);
angular.module("FICApp") angular.module("FICApp")

View file

@ -1,86 +0,0 @@
<div class="d-flex justify-content-between align-items-center">
<h2>
Authentification
</h2>
<div>
<div class="btn-group mr-1" role="group">
<button type="button" ng-click="generateHtpasswd()" class="btn btn-sm btn-secondary"><span class="glyphicon glyphicon-save-file" aria-hidden="true"></span> Générer <code>fichtpasswd</code></button>
<button type="button" ng-click="removeHtpasswd()" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button>
</div>
</div>
</div>
<div ng-controller="OAuthController">
<div class="d-flex justify-content-between align-items-center">
<h3>
OAuth 2
<span class="badge badge-success" ng-if="oauth_status.secret_defined">Actif</span>
<span class="badge badge-danger" ng-if="!oauth_status.secret_defined">Non configuré</span>
</h3>
<div>
<button type="button" ng-click="genDexCfg()" class="btn btn-success mr-2"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> DexIdP</button>
</div>
</div>
</div>
<hr>
<div ng-controller="PKIController">
<div class="d-flex justify-content-between align-items-center">
<h3>
Autorité de certification
<span class="badge badge-success" ng-if="ca.version">Générée</span>
<span class="badge badge-danger" ng-if="!ca.version">Introuvable</span>
</h3>
<div>
<a
class="btn btn-primary"
href="/pki"
>
<span class="glyphicon glyphicon-certificate" aria-hidden="true"></span>
Gérer la PKI
</a>
</div>
</div>
<div class="alert alert-info" ng-if="!ca.version">
<strong>Aucune CA n'a été générée pour le moment.</strong>
</div>
<dl ng-if="ca.version">
<ng-repeat ng-repeat="(k, v) in ca" class="row">
<dt class="col-3 text-right">{{ k }}</dt>
<dd class="col-9" ng-if="v.CommonName">/CN={{ v.CommonName }}/OU={{ v.OrganizationalUnit }}/O={{ v.Organization }}/L={{ v.Locality }}/P={{ v.Province }}/C={{ v.Country }}/</dd>
<dd class="col-9" ng-if="!v.CommonName">{{ v }}</dd>
</ng-repeat>
</dl>
</div>
<hr>
<div class="mb-4" ng-controller="AllTeamAssociationsController">
<div class="d-flex justify-content-between align-items-center">
<h3>
Association utilisateurs et équipes
</h3>
<div>
</div>
</div>
<table class="table table-sm table-hover" ng-controller="TeamsListController" >
<tr>
<th class="text-right">Utilisateur</th>
<th></th>
<th>Équipe</th>
</tr>
<tr ng-repeat="association in allAssociations">
<td class="text-right">{{ association.association }}</td>
<td class="text-center">&#11020;</td>
<td ng-repeat="team in teams" ng-if="team.id == association.team_id">
<a ng-href="teams/{{ team.id }}">
{{ team.name }}
</a>
</td>
</tr>
</table>
</div>

View file

@ -73,28 +73,12 @@
</div> </div>
<div class="col-4"> <div class="col-4">
<div ng-controller="ExerciceFlagDepsController" ng-init="init(flag)"> <div ng-controller="ExerciceFlagDepsController" ng-init="init(flag)">
<strong>Dépendances&nbsp;:</strong> Dépendances&nbsp;:
<ul ng-if="deps.length > 0"> <ul ng-if="deps.length > 0">
<dependancy ng-repeat="dep in deps" dep="dep"></dependancy> <dependancy ng-repeat="dep in deps" dep="dep"></dependancy>
</ul> </ul>
<span ng-if="deps.length == 0"> sans</span> <span ng-if="deps.length == 0"> sans</span>
</div> </div>
<hr>
<div ng-controller="ExerciceFlagStatsController" ng-init="init(flag)">
<strong>Statistiques</strong>
<ul>
<li>Validés: {{ stats["completed"] }}</li>
<li>
Tentés: {{ stats["tries"] }}
<button type="button" ng-click="deleteTries()" class="btn btn-sm btn-danger" ng-if="stats['tries'] > 0"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button>
</li>
<li>
Équipes:
<span ng-if="stats['teams'].length == 0">aucune</span>
<team-link ng-repeat="team in stats['teams']" id-team="team"></team-link>
</li>
</ul>
</div>
</div> </div>
<div class="col-4" ng-controller="ExerciceFlagChoicesController"> <div class="col-4" ng-controller="ExerciceFlagChoicesController">
<div class="btn-toolbar justify-content-end mb-2" role="toolbar"> <div class="btn-toolbar justify-content-end mb-2" role="toolbar">
@ -184,22 +168,6 @@
<dependancy ng-repeat="dep in deps" dep="dep"></dependancy> <dependancy ng-repeat="dep in deps" dep="dep"></dependancy>
</ul> </ul>
<span ng-if="deps.length == 0"> sans</span> <span ng-if="deps.length == 0"> sans</span>
<hr>
<div ng-controller="ExerciceMCQStatsController" ng-init="init(q)">
<strong>Statistiques</strong>
<ul>
<li>Validés: {{ stats["completed"] }}</li>
<li>
Tentés: {{ stats["tries"] }}
<button type="button" ng-click="deleteTries()" class="btn btn-sm btn-danger" ng-if="stats['tries'] > 0"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button>
</li>
<li>
Équipes:
<span ng-if="stats['teams'].length == 0">aucune</span>
<team-link ng-repeat="team in stats['teams']" id-team="team"></team-link>
</li>
</ul>
</div>
</div> </div>
</form> </form>
</div> </div>

View file

@ -100,7 +100,7 @@
<form ng-submit="saveFile()" class="list-group-item bg-light text-dark" ng-repeat="file in files"> <form ng-submit="saveFile()" class="list-group-item bg-light text-dark" ng-repeat="file in files">
<div class="row form-group"> <div class="row form-group">
<input type="text" ng-model="file.name" class="col form-control form-control-sm" placeholder="Nom de fichier"> <input type="text" ng-model="file.name" class="col form-control form-control-sm" placeholder="Nom de fichier">
<a href="../files{{file.path}}" target="_self" class="btn btn-sm btn-secondary col-auto"><span class="glyphicon glyphicon-download" aria-hidden="true"></span></a> <a href="../files{{file.path}}" class="btn btn-sm btn-secondary col-auto"><span class="glyphicon glyphicon-download" aria-hidden="true"></span></a>
<button type="submit" class="btn btn-sm btn-success col-auto"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button><br> <button type="submit" class="btn btn-sm btn-success col-auto"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button><br>
<button type="button" ng-click="deleteFile()" class="btn btn-sm btn-danger col-auto"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button> <button type="button" ng-click="deleteFile()" class="btn btn-sm btn-danger col-auto"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
</div> </div>

View file

@ -30,13 +30,13 @@
<div class="spinner-border spinner-border-sm" role="status" ng-if="file.gunzipWIP"></div> <div class="spinner-border spinner-border-sm" role="status" ng-if="file.gunzipWIP"></div>
</button> </button>
</td> </td>
<td ng-repeat="field in fields" class="text-truncate" style="max-width: 30vw" title="{{ file[field] }}"> <td ng-repeat="field in fields">
{{ file[field] }} {{ file[field] }}
<span ng-if="field == 'id' && file.err !== undefined && file.err !== true" title="{{ file.err }}" class="glyphicon glyphicon-exclamation-sign"></span> <span ng-if="field == 'id' && file.err !== undefined && file.err !== true" title="{{ file.err }}" class="glyphicon glyphicon-exclamation-sign"></span>
</td> </td>
<td style="max-width: 100px"> <td>
<div class="text-truncate" title="{{ file.checksum | bto16 }}">{{ file.checksum | bto16 }}</div> {{ file.checksum | bto16 }}
<div class="text-truncate" ng-if="file.checksum_shown" title="{{ file.checksum_shown | bto16 }}">{{ file.checksum_shown | bto16 }}</div> <div ng-if="file.checksum_shown">{{ file.checksum_shown | bto16 }}</div>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View file

@ -35,7 +35,7 @@
<label for="startTime" class="col-sm-3 col-form-label col-form-label-sm" ng-class="{'text-primary font-weight-bold': config.start != dist_config.start}">Début du challenge</label> <label for="startTime" class="col-sm-3 col-form-label col-form-label-sm" ng-class="{'text-primary font-weight-bold': config.start != dist_config.start}">Début du challenge</label>
<div class="col-sm-9"> <div class="col-sm-9">
<div class="input-group"> <div class="input-group">
<input type="datetime-local" class="form-control form-control-sm" id="startTime" ng-model="config.start" ng-change="durationChange()" ng-class="{'border-primary': config.start != dist_config.start}"> <input type="datetime-local" class="form-control form-control-sm" id="startTime" ng-model="config.start" ng-class="{'border-primary': config.start != dist_config.start}">
<div class="input-group-append"> <div class="input-group-append">
<button ng-click="launchChallenge()" class="btn btn-sm btn-secondary" type="button"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Lancer le challenge</button> <button ng-click="launchChallenge()" class="btn btn-sm btn-secondary" type="button"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Lancer le challenge</button>
</div> </div>
@ -46,14 +46,14 @@
<div class="form-group row"> <div class="form-group row">
<label for="endTime" class="col-sm-3 col-form-label col-form-label-sm" ng-class="{'text-primary font-weight-bold': config.end != dist_config.end}">Fin du challenge</label> <label for="endTime" class="col-sm-3 col-form-label col-form-label-sm" ng-class="{'text-primary font-weight-bold': config.end != dist_config.end}">Fin du challenge</label>
<div class="col-sm-6"> <div class="col-sm-6">
<input type="datetime-local" class="form-control form-control-sm" id="endTime" ng-model="config.end" ng-change="durationChange(true)" ng-class="{'border-primary': config.end != dist_config.end}"> <input type="datetime-local" class="form-control form-control-sm" id="endTime" ng-model="config.end" ng-class="{'border-primary': config.end != dist_config.end}">
</div> </div>
<div class="col-sm-1 text-right"> <div class="col-sm-1 text-right">
<label for="duration" class="col-form-label col-form-label-sm">Durée</label> <label for="duration" class="col-form-label col-form-label-sm">Durée</label>
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="number" class="form-control form-control-sm" id="duration" ng-model="duration" ng-change="durationChange()" integer> <input type="text" class="form-control form-control-sm" id="duration" ng-model="duration" integer>
<div class="input-group-append"> <div class="input-group-append">
<span class="input-group-text">min</span> <span class="input-group-text">min</span>
</div> </div>
@ -323,7 +323,7 @@
<form class="row" ng-controller="AllTeamAssociationsController" ng-submit="addDelegatedQA()"> <form class="row" ng-controller="AllTeamAssociationsController" ng-submit="addDelegatedQA()">
<div class="col"> <div class="col">
<select class="form-control form-control-sm" ng-model="newdqa"> <select class="form-control form-control-sm" ng-model="newdqa">
<option ng-selected="newdqa == m.association" ng-repeat="(i,m) in allAssociations" ng-value="m.association">{{ m.association }}</option> <option ng-selected="newdqa == m" ng-repeat="(i,m) in allAssociations" ng-value="m">{{ m }}</option>
</select> </select>
</div> </div>
<div class="col input-group"> <div class="col input-group">

View file

@ -1,19 +1,11 @@
<div class="d-flex justify-content-between align-items-center"> <h2>
<h2> &Eacute;quipes
&Eacute;quipes <button type="button" ng-click="show('new')" class="float-right btn btn-sm btn-primary"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Ajouter une équipe</button>
</h2> <button type="button" ng-click="show('print')" class="float-right btn btn-sm btn-secondary mr-2"><span class="glyphicon glyphicon-print" aria-hidden="true"></span> Imprimer les équipes</button>
<div> <button type="button" ng-click="show('export')" class="float-right btn btn-sm btn-secondary mr-2"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Statistiques générales</button>
<button type="button" ng-click="show('new')" class="btn btn-sm btn-primary ml-1"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Ajouter une équipe</button> <button type="button" ng-click="desactiveTeams()" class="float-right btn btn-sm btn-danger mr-2" title="Cliquer pour marquer les équipes sans certificat comme inactives (et ainsi éviter que ses fichiers ne soient générés)"><span class="glyphicon glyphicon-leaf" aria-hidden="true"></span> Désactiver les équipes inactives</button>
<form class="d-inline"> <button type="button" ng-click="genDexCfg()" class="float-right btn btn-sm btn-success mr-2"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> DexIdP</button>
<input id="crTeamsInput" type="file" file-model="selectedFile" class="d-none" /> </h2>
<button type="button" ng-click="triggerTeamsImport()" class="btn btn-sm btn-secondary ml-1"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import Cyberrange</button>
</form>
<button type="button" ng-click="show('print')" class="btn btn-sm btn-secondary ml-1" title="Imprimer les équipes et leurs membres"><span class="glyphicon glyphicon-print" aria-hidden="true"></span></button>
<button type="button" ng-click="refineTeamsColors()" class="btn btn-sm btn-secondary ml-1" title="Réarranger automatiquement les couleurs des équipes pour maximiser le spectre utilisé"><span class="glyphicon glyphicon-adjust" aria-hidden="true"></span></button>
<button type="button" ng-click="show('export')" class="btn btn-sm btn-secondary ml-1"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Statistiques générales</button>
<button type="button" ng-click="desactiveTeams()" class="btn btn-sm btn-danger ml-1" title="Cliquer pour marquer les équipes sans certificat comme inactives (et ainsi éviter que ses fichiers ne soient générés)"><span class="glyphicon glyphicon-leaf" aria-hidden="true"></span> Désactiver les équipes inactives</button>
</div>
</div>
<p><input type="search" class="form-control" placeholder="Search" ng-model="query" ng-keypress="validateSearch($event)" autofocus></p> <p><input type="search" class="form-control" placeholder="Search" ng-model="query" ng-keypress="validateSearch($event)" autofocus></p>
<table class="table table-hover table-bordered table-striped table-sm"> <table class="table table-hover table-bordered table-striped table-sm">

View file

@ -279,7 +279,6 @@ func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defau
} }
type importFlag struct { type importFlag struct {
origin ExerciceFlag
Line int Line int
Flag fic.Flag Flag fic.Flag
JustifyOf *fic.MCQ_entry JustifyOf *fic.MCQ_entry
@ -393,9 +392,8 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
errs = multierr.Append(errs, berrs) errs = multierr.Append(errs, berrs)
if addedFlag != nil { if addedFlag != nil {
ret = append(ret, importFlag{ ret = append(ret, importFlag{
origin: flag, Line: nline + 1,
Line: nline + 1, Flag: addedFlag,
Flag: addedFlag,
}) })
} }
} else if flag.Type == "key" || strings.HasPrefix(flag.Type, "number") || flag.Type == "text" || flag.Type == "ucq" || flag.Type == "radio" || flag.Type == "vector" { } else if flag.Type == "key" || strings.HasPrefix(flag.Type, "number") || flag.Type == "text" || flag.Type == "ucq" || flag.Type == "radio" || flag.Type == "vector" {
@ -403,7 +401,6 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
errs = multierr.Append(errs, berrs) errs = multierr.Append(errs, berrs)
if addedFlag != nil { if addedFlag != nil {
ret = append(ret, importFlag{ ret = append(ret, importFlag{
origin: flag,
Line: nline + 1, Line: nline + 1,
Flag: *addedFlag, Flag: *addedFlag,
Choices: choices, Choices: choices,
@ -465,7 +462,6 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
errs = multierr.Append(errs, berrs) errs = multierr.Append(errs, berrs)
if addedFlag != nil { if addedFlag != nil {
ret = append(ret, importFlag{ ret = append(ret, importFlag{
origin: flag,
Line: nline + 1, Line: nline + 1,
Flag: *addedFlag, Flag: *addedFlag,
JustifyOf: entry, JustifyOf: entry,
@ -483,9 +479,8 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl
} }
ret = append([]importFlag{importFlag{ ret = append([]importFlag{importFlag{
origin: flag, Line: nline + 1,
Line: nline + 1, Flag: &addedFlag,
Flag: &addedFlag,
}}, ret...) }}, ret...)
} }
return return
@ -575,10 +570,6 @@ func CheckExerciceFlags(i Importer, exercice *fic.Exercice, files []string, exce
if int64(fk.ChoicesCost) >= exercice.Gain { if int64(fk.ChoicesCost) >= exercice.Gain {
errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag's choice_cost is higher than exercice gain"))) errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag's choice_cost is higher than exercice gain")))
} }
if raw, ok := flag.origin.Raw.(string); ok && raw == fk.Placeholder {
errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag's placeholder and raw are identical")))
}
} }
// Check dependency loop // Check dependency loop

View file

@ -238,21 +238,3 @@ func WriteFileContent(i Importer, URI string, content []byte) error {
return fmt.Errorf("%t is not capable of writing", i) return fmt.Errorf("%t is not capable of writing", i)
} }
} }
func OpenOrGetFile(i Importer, URI string) (fd io.Reader, closer func() error, err error) {
if strings.HasPrefix(URI, "$FILES$") {
var fdc io.ReadCloser
fdc, err = os.Open(path.Join(fic.FilesDir, strings.TrimPrefix(URI, "$FILES$/")))
fd = fdc
closer = fdc.Close
} else {
fd, err = GlobalImporter.GetFile(URI)
if fdcloser, ok := fd.(io.ReadCloser); ok {
closer = fdcloser.Close
} else {
closer = func() error { return nil }
}
}
return
}

View file

@ -20,8 +20,6 @@ escape_newline () {
sed 's/$/\\n/g' | tr -d '\n' sed 's/$/\\n/g' | tr -d '\n'
} }
which mkisofs > /dev/null 2> /dev/null || { echo "Please install genisoimage (Debian/Ubuntu) or cdrkit (Alpine)" >&2; exit 1; }
if [ $# -gt 0 ] if [ $# -gt 0 ]
then then
which jq > /dev/null 2> /dev/null || { echo "Please install jq" >&2; exit 1; } which jq > /dev/null 2> /dev/null || { echo "Please install jq" >&2; exit 1; }

View file

@ -21,8 +21,6 @@ OLD_KEY=$(cat /run/config/dm-crypt/key)
[ "${NEW_KEY}" != "${OLD_KEY}" ] && { [ "${NEW_KEY}" != "${OLD_KEY}" ] && {
read -p "DM-CRYPT key changed in metadata, are you sure you want to erase it? (y/N) " V read -p "DM-CRYPT key changed in metadata, are you sure you want to erase it? (y/N) " V
[ "$V" != "y" ] && [ "$V" != "Y" ] && while true; do [ "$V" != "y" ] && [ "$V" != "Y" ] && while true; do
mv /boot/imgs/fickit-metadata.iso /boot/imgs/fickit-metadata.iso.skipped
cp /boot/imgs/fickit-metadata.iso.bak /boot/imgs/fickit-metadata.iso
echo echo
echo "Metadata drive not erased" echo "Metadata drive not erased"
echo echo

View file

@ -1,54 +1,54 @@
kernel: kernel:
#image: nemunaire/kernel:5.10.62-0b705d955f5e283f62583c4e227d64a7924c138f-amd64 #image: nemunaire/kernel:5.10.62-0b705d955f5e283f62583c4e227d64a7924c138f-amd64
image: linuxkit/kernel:6.6.71 image: linuxkit/kernel:6.6.13
cmdline: "console=ttyS0 console=tty0" cmdline: "console=ttyS0 console=tty0"
init: init:
- linuxkit/init:8eea386739975a43af558eec757a7dcb3a3d2e7b - linuxkit/init:7135424f6836ee166d1199e88cfb95ee88efaf91
- linuxkit/runc:667e7ea2c426a2460ca21e3da065a57dbb3369c9 - linuxkit/runc:efcece75889aec4e2de0d95ba27ccc46438522b3
- linuxkit/containerd:a988a1a8bcbacc2c0390ca0c08f949e2b4b5915d - linuxkit/containerd:ce79d5d4ab9c46f4763735c6e4ab5c51c3feb5d8
- linuxkit/ca-certificates:7b32a26ca9c275d3ef32b11fe2a83dbd2aee2fdb - linuxkit/ca-certificates:d4cc1b82c73d272e94d0e71ea375fe56b0c0626a
- linuxkit/getty:05eca453695984a69617f1f1f0bcdae7f7032967 - linuxkit/getty:bae9e3d4861173bacf78f14a4fe44997a430d13b
- nemunaire/mdadm:04814350d71ba9417e1f861be1685de26adf7a67 - nemunaire/mdadm:04814350d71ba9417e1f861be1685de26adf7a67
- nemunaire/kexec:839b4eedfce02a56c581dec2383dc6faff120855 - nemunaire/kexec:839b4eedfce02a56c581dec2383dc6faff120855
onboot: onboot:
- name: mod - name: mod
image: linuxkit/modprobe:773ee174006ecbb412830e48889795bae40b62f9 image: linuxkit/modprobe:e3de97ac10970edee33faa78d9780117174bd1ac
command: ["/bin/sh", "-c", "modprobe xhci_pci ahci intel_lpss_pci i2c_i801 megaraid_sas tg3 bnxt_en"] command: ["/bin/sh", "-c", "modprobe xhci_pci ahci intel_lpss_pci i2c_i801 megaraid_sas tg3 bnxt_en"]
- name: sysctl - name: sysctl
image: linuxkit/sysctl:5f56434b81004b50b47ed629b222619168c2bcdf image: linuxkit/sysctl:c5f4b4895844b993dce4e8b35fd8263a6b557807
binds: binds:
- /etc/sysctl.d/01-fic.conf:/etc/sysctl.d/01-fic.conf:ro - /etc/sysctl.d/01-fic.conf:/etc/sysctl.d/01-fic.conf:ro
# Metadata # Metadata
- name: metadata - name: metadata
image: linuxkit/metadata:4f81c0c3a2b245567fd7d32d799018c9614a9907 image: linuxkit/metadata:f35b5aafc7d19bb6a44a900840727902dad78e44
command: ["/usr/bin/metadata", "-v", "cdrom"] command: ["/usr/bin/metadata", "-v", "cdrom"]
# Filesystem # Filesystem
- name: swap - name: swap
image: linuxkit/swap:f4b8ffef87c8c72165bd8a92b790ac252ccf1821 image: linuxkit/swap:8a1fd15d56b6ddf67d6d8ce25361178e1f36128b
command: ["/sbin/swapon", "/dev/sda3"] command: ["/sbin/swapon", "/dev/sda3"]
- name: dm-crypt - name: dm-crypt
image: linuxkit/dm-crypt:981fde241bb84616a5ba94c04cdefa1489431a25 image: linuxkit/dm-crypt:19fa6affe9da03afc91694e36d72a4924c65a0e0
command: ["/usr/bin/crypto", "-l", "crypt_fic", "/dev/sda4"] command: ["/usr/bin/crypto", "-l", "crypt_fic", "/dev/sda4"]
binds: binds:
- /dev:/dev - /dev:/dev
- /run/config/dm-crypt:/etc/dm-crypt - /run/config/dm-crypt:/etc/dm-crypt
- name: mount - name: mount
image: linuxkit/mount:cb8caa72248f7082fc2074ce843d53cdc15df04a image: linuxkit/mount:4413ebd50bfbe026058e4a60463259cece2b8bb5
command: ["/usr/bin/mountie", "-device", "/dev/mapper/crypt_fic", "/var/lib/fic" ] command: ["/usr/bin/mountie", "-device", "/dev/mapper/crypt_fic", "/var/lib/fic" ]
# Network # Network
# - name: dhcpcd # - name: dhcpcd
# image: linuxkit/dhcpcd:157df9ef45a035f1542ec2270e374f18efef98a5 # image: linuxkit/dhcpcd:330839488cd122db3c44738e265c035c9729a963
# command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"] # command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"]
# - name: ntp # - name: ntp
# image: linuxkit/openntpd:f99c4117763480815553b72022b426639a13ce86 # image: linuxkit/openntpd:da26954c2f98a274091e5ed0bbdd2079a77a47c1
- name: synchro-ip-setup - name: synchro-ip-setup
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/sh", "-c", "ip a add 10.10.10.1/29 dev eth2; ip link set eth2 up;" ] command: ["/bin/sh", "-c", "ip a add 10.10.10.1/29 dev eth2; ip link set eth2 up;" ]
net: new net: new
runtime: runtime:
@ -57,7 +57,7 @@ onboot:
bindNS: bindNS:
net: /run/netns/synchro net: /run/netns/synchro
- name: qa-ip-setup - name: qa-ip-setup
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/sh", "-c", "ip link show eth1 2> /dev/null && { ip a add 10.10.10.1/29 dev eth1; ip link set eth1 up; }; ip a add 172.17.0.6/24 dev vethin-qa; ip link set vethin-qa up" ] command: ["/bin/sh", "-c", "ip link show eth1 2> /dev/null && { ip a add 10.10.10.1/29 dev eth1; ip link set eth1 up; }; ip a add 172.17.0.6/24 dev vethin-qa; ip link set vethin-qa up" ]
net: new net: new
runtime: runtime:
@ -69,7 +69,7 @@ onboot:
bindNS: bindNS:
net: /run/netns/fic-qa net: /run/netns/fic-qa
- name: admin-ip-setup - name: admin-ip-setup
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
#command: ["/bin/sh", "-c", "ip link add link eth3 name adminiface type vlan id 99; ip a add 172.16.99.219/24 dev adminiface; ip link set eth3 up; ip link set adminiface up; ip r add default via 172.16.99.1; ip a add 172.17.0.2/24 dev vethin-admin; ip link set vethin-admin up; ping -W 10 -c 1 172.16.99.1;" ] #command: ["/bin/sh", "-c", "ip link add link eth3 name adminiface type vlan id 99; ip a add 172.16.99.219/24 dev adminiface; ip link set eth3 up; ip link set adminiface up; ip r add default via 172.16.99.1; ip a add 172.17.0.2/24 dev vethin-admin; ip link set vethin-admin up; ping -W 10 -c 1 172.16.99.1;" ]
command: ["/bin/sh", "-c", "ip link set eth3 up; while read IP; do ip a add ${IP} dev eth3; done < /run/config/ip_config/backend-admin; ip r add default via $(cat /run/config/ip_config/backend-router); ip a add 172.17.0.2/24 dev vethin-admin; ip link set vethin-admin up; echo 'Waiting for' $(cat /run/config/ip_config/backend-router); ping -W 10 -c 1 $(cat /run/config/ip_config/backend-router); ip link show eth1 2> /dev/null && { ip a add 10.0.0.1/24 dev eth1; ip link set eth1 up; };" ] command: ["/bin/sh", "-c", "ip link set eth3 up; while read IP; do ip a add ${IP} dev eth3; done < /run/config/ip_config/backend-admin; ip r add default via $(cat /run/config/ip_config/backend-router); ip a add 172.17.0.2/24 dev vethin-admin; ip link set vethin-admin up; echo 'Waiting for' $(cat /run/config/ip_config/backend-router); ping -W 10 -c 1 $(cat /run/config/ip_config/backend-router); ip link show eth1 2> /dev/null && { ip a add 10.0.0.1/24 dev eth1; ip link set eth1 up; };" ]
net: new net: new
@ -85,7 +85,7 @@ onboot:
bindNS: bindNS:
net: /run/netns/fic-admin net: /run/netns/fic-admin
- name: checker-ip-setup - name: checker-ip-setup
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/sh", "-c", "ip a add 172.17.0.3/24 dev vethin-checker; ip link set vethin-checker up;" ] command: ["/bin/sh", "-c", "ip a add 172.17.0.3/24 dev vethin-checker; ip link set vethin-checker up;" ]
net: new net: new
runtime: runtime:
@ -96,7 +96,7 @@ onboot:
bindNS: bindNS:
net: /run/netns/fic-checker net: /run/netns/fic-checker
- name: generator-ip-setup - name: generator-ip-setup
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/sh", "-c", "ip a add 172.17.0.5/24 dev vethin-generat; ip link set vethin-generat up;" ] command: ["/bin/sh", "-c", "ip a add 172.17.0.5/24 dev vethin-generat; ip link set vethin-generat up;" ]
net: new net: new
runtime: runtime:
@ -107,7 +107,7 @@ onboot:
bindNS: bindNS:
net: /run/netns/fic-generator net: /run/netns/fic-generator
- name: mysql-ip-setup - name: mysql-ip-setup
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/sh", "-c", "ip a add 172.17.0.4/24 dev vethin-db; ip link set vethin-db up;" ] command: ["/bin/sh", "-c", "ip a add 172.17.0.4/24 dev vethin-db; ip link set vethin-db up;" ]
net: new net: new
runtime: runtime:
@ -118,7 +118,7 @@ onboot:
bindNS: bindNS:
net: /run/netns/db net: /run/netns/db
- name: bridge-setup - name: bridge-setup
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/sh", "-c", "ip a add 172.17.0.1/24 dev br0; ip link set veth-admin master br0; ip link set veth-checker master br0; ip link set veth-generator master br0; ip link set veth-db master br0; ip link set veth-qa master br0; ip link set br0 up; ip link set veth-admin up; ip link set veth-checker up; ip link set veth-generator up; ip link set veth-db up; ip link set veth-qa up;" ] command: ["/bin/sh", "-c", "ip a add 172.17.0.1/24 dev br0; ip link set veth-admin master br0; ip link set veth-checker master br0; ip link set veth-generator master br0; ip link set veth-db master br0; ip link set veth-qa master br0; ip link set br0 up; ip link set veth-admin up; ip link set veth-checker up; ip link set veth-generator up; ip link set veth-db up; ip link set veth-qa up;" ]
runtime: runtime:
interfaces: interfaces:
@ -126,7 +126,7 @@ onboot:
add: bridge add: bridge
- name: firewall-synchro - name: firewall-synchro
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/bash", "-c", "/sbin/iptables-restore < /etc/iptables/rules-synchro.v4; /sbin/ip6tables-restore < /etc/iptables/rules.v6" ] command: ["/bin/bash", "-c", "/sbin/iptables-restore < /etc/iptables/rules-synchro.v4; /sbin/ip6tables-restore < /etc/iptables/rules.v6" ]
binds: binds:
- /etc/iptables/rules-synchro.v4:/etc/iptables/rules-synchro.v4:ro - /etc/iptables/rules-synchro.v4:/etc/iptables/rules-synchro.v4:ro
@ -136,7 +136,7 @@ onboot:
mkdir: mkdir:
- /var/lib/fic/teams - /var/lib/fic/teams
- name: firewall-admin - name: firewall-admin
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/bash", "-c", "/sbin/iptables-restore < /etc/iptables/rules-admin.v4; /sbin/ip6tables-restore < /etc/iptables/rules.v6" ] command: ["/bin/bash", "-c", "/sbin/iptables-restore < /etc/iptables/rules-admin.v4; /sbin/ip6tables-restore < /etc/iptables/rules.v6" ]
binds: binds:
- /etc/iptables/rules-admin.v4:/etc/iptables/rules-admin.v4:ro - /etc/iptables/rules-admin.v4:/etc/iptables/rules-admin.v4:ro
@ -153,26 +153,17 @@ onboot:
mkdir: mkdir:
- /var/lib/fic/secrets - /var/lib/fic/secrets
- name: create-ssh-keys
image: nemunaire/rsync:a3d76b2dd0a9ad73be44dc77ad765b20d96a3285
command: ["/bin/sh", "-c", "touch /etc/ssh/sshd_config && ssh-keygen -A"]
binds:
- /var/lib/fic/ssh:/etc/ssh
runtime:
mkdir:
- /var/lib/fic/ssh
services: services:
# - name: getty # - name: getty
# image: linuxkit/getty:05eca453695984a69617f1f1f0bcdae7f7032967 # image: linuxkit/getty:bae9e3d4861173bacf78f14a4fe44997a430d13b
# env: # env:
# - INSECURE=true # - INSECURE=true
# Enable acpi to shutdown on power events # Enable acpi to shutdown on power events
- name: acpid - name: acpid
image: linuxkit/acpid:6cb5575e487a8fcbd4c3eb6721c23299e6ea452f image: linuxkit/acpid:6379700e2f3341250432e37a4cac36e35c7caac8
- name: rngd - name: rngd
image: linuxkit/rngd:1a18f2149e42a0a1cb9e7d37608a494342c26032 image: linuxkit/rngd:814d1a3a76e84eae01a94575c038fd22652f94e3
- name: db - name: db
image: mariadb:11 image: mariadb:11
command: ["/bin/bash", "/usr/local/bin/docker-entrypoint.sh", "mariadbd"] command: ["/bin/bash", "/usr/local/bin/docker-entrypoint.sh", "mariadbd"]
@ -237,7 +228,7 @@ services:
- /var/lib/fic/generator:/srv/GENERATOR:ro - /var/lib/fic/generator:/srv/GENERATOR:ro
- /var/lib/fic/pki:/srv/PKI - /var/lib/fic/pki:/srv/PKI
- /var/lib/fic/settings:/srv/SETTINGS - /var/lib/fic/settings:/srv/SETTINGS
- /var/lib/fic/submissions:/srv/submissions - /var/lib/fic/submissions:/srv/submissions:ro
- /var/lib/fic/sync:/srv/SYNC - /var/lib/fic/sync:/srv/SYNC
- /var/lib/fic/teams:/srv/TEAMS - /var/lib/fic/teams:/srv/TEAMS
net: /run/netns/fic-admin net: /run/netns/fic-admin
@ -278,10 +269,7 @@ services:
binds: binds:
- /etc/hosts:/etc/hosts:ro - /etc/hosts:/etc/hosts:ro
- /var/lib/fic/generator:/srv/GENERATOR:ro - /var/lib/fic/generator:/srv/GENERATOR:ro
# Uncomment this to disallow registrations
- /var/lib/fic/teams:/srv/TEAMS:ro - /var/lib/fic/teams:/srv/TEAMS:ro
# Uncomment this to allow registrations
#- /var/lib/fic/teams:/srv/TEAMS
- /var/lib/fic/secrets/mysql_password:/run/secrets/mysql_password:ro - /var/lib/fic/secrets/mysql_password:/run/secrets/mysql_password:ro
- /var/lib/fic/settingsdist:/srv/SETTINGSDIST:ro - /var/lib/fic/settingsdist:/srv/SETTINGSDIST:ro
- /var/lib/fic/submissions:/srv/submissions - /var/lib/fic/submissions:/srv/submissions
@ -373,6 +361,7 @@ services:
- /var/lib/fic/files - /var/lib/fic/files
- /var/lib/fic/pki/shared - /var/lib/fic/pki/shared
- /var/lib/fic/settingsdist - /var/lib/fic/settingsdist
- /var/lib/fic/ssh
- /var/lib/fic/submissions - /var/lib/fic/submissions
- /var/lib/fic/teams - /var/lib/fic/teams
- /var/log/frontend - /var/log/frontend

View file

@ -1,6 +1,6 @@
kernel: kernel:
#image: nemunaire/kernel:5.10.62-0b705d955f5e283f62583c4e227d64a7924c138f-amd64 #image: nemunaire/kernel:5.10.62-0b705d955f5e283f62583c4e227d64a7924c138f-amd64
image: linuxkit/kernel:6.6.71 image: linuxkit/kernel:6.6.13
cmdline: "console=ttyS0 console=tty0" cmdline: "console=ttyS0 console=tty0"
init: init:

View file

@ -1,50 +1,50 @@
kernel: kernel:
#image: nemunaire/kernel:5.10.62-0b705d955f5e283f62583c4e227d64a7924c138f-amd64 #image: nemunaire/kernel:5.10.62-0b705d955f5e283f62583c4e227d64a7924c138f-amd64
image: linuxkit/kernel:6.6.71 image: linuxkit/kernel:6.6.13
cmdline: "console=ttyS0 console=tty0" cmdline: "console=ttyS0 console=tty0"
init: init:
- linuxkit/init:8eea386739975a43af558eec757a7dcb3a3d2e7b - linuxkit/init:7135424f6836ee166d1199e88cfb95ee88efaf91
- linuxkit/runc:667e7ea2c426a2460ca21e3da065a57dbb3369c9 - linuxkit/runc:efcece75889aec4e2de0d95ba27ccc46438522b3
- linuxkit/containerd:a988a1a8bcbacc2c0390ca0c08f949e2b4b5915d - linuxkit/containerd:ce79d5d4ab9c46f4763735c6e4ab5c51c3feb5d8
- linuxkit/ca-certificates:7b32a26ca9c275d3ef32b11fe2a83dbd2aee2fdb - linuxkit/ca-certificates:d4cc1b82c73d272e94d0e71ea375fe56b0c0626a
- linuxkit/getty:05eca453695984a69617f1f1f0bcdae7f7032967 - linuxkit/getty:bae9e3d4861173bacf78f14a4fe44997a430d13b
- nemunaire/mdadm:04814350d71ba9417e1f861be1685de26adf7a67 - nemunaire/mdadm:04814350d71ba9417e1f861be1685de26adf7a67
- nemunaire/kexec:839b4eedfce02a56c581dec2383dc6faff120855 - nemunaire/kexec:839b4eedfce02a56c581dec2383dc6faff120855
- nemunaire/fic-frontend-ui:latest - nemunaire/fic-frontend-ui:latest
onboot: onboot:
- name: mod - name: mod
image: linuxkit/modprobe:773ee174006ecbb412830e48889795bae40b62f9 image: linuxkit/modprobe:e3de97ac10970edee33faa78d9780117174bd1ac
command: ["/bin/sh", "-c", "modprobe xhci_pci ahci intel_lpss_pci i2c_i801 megaraid_sas tg3 bnxt_en"] command: ["/bin/sh", "-c", "modprobe xhci_pci ahci intel_lpss_pci i2c_i801 megaraid_sas tg3 bnxt_en"]
- name: sysctl - name: sysctl
image: linuxkit/sysctl:5f56434b81004b50b47ed629b222619168c2bcdf image: linuxkit/sysctl:c5f4b4895844b993dce4e8b35fd8263a6b557807
# Metadata # Metadata
- name: metadata - name: metadata
image: linuxkit/metadata:4f81c0c3a2b245567fd7d32d799018c9614a9907 image: linuxkit/metadata:f35b5aafc7d19bb6a44a900840727902dad78e44
command: ["/usr/bin/metadata", "-v", "cdrom"] command: ["/usr/bin/metadata", "-v", "cdrom"]
# Filesystem # Filesystem
- name: swap - name: swap
image: linuxkit/swap:f4b8ffef87c8c72165bd8a92b790ac252ccf1821 image: linuxkit/swap:8a1fd15d56b6ddf67d6d8ce25361178e1f36128b
command: ["/sbin/swapon", "/dev/sda3"] command: ["/sbin/swapon", "/dev/sda3"]
- name: dm-crypt - name: dm-crypt
image: linuxkit/dm-crypt:981fde241bb84616a5ba94c04cdefa1489431a25 image: linuxkit/dm-crypt:19fa6affe9da03afc91694e36d72a4924c65a0e0
command: ["/usr/bin/crypto", "-l", "crypt_fic", "/dev/sda4"] command: ["/usr/bin/crypto", "-l", "crypt_fic", "/dev/sda4"]
binds: binds:
- /dev:/dev - /dev:/dev
- /run/config/dm-crypt:/etc/dm-crypt - /run/config/dm-crypt:/etc/dm-crypt
- name: mount - name: mount
image: linuxkit/mount:cb8caa72248f7082fc2074ce843d53cdc15df04a image: linuxkit/mount:4413ebd50bfbe026058e4a60463259cece2b8bb5
command: ["/usr/bin/mountie", "-device", "/dev/mapper/crypt_fic", "/var/lib/fic" ] command: ["/usr/bin/mountie", "-device", "/dev/mapper/crypt_fic", "/var/lib/fic" ]
# Network # Network
# - name: ntp # - name: ntp
# image: linuxkit/openntpd:f99c4117763480815553b72022b426639a13ce86 # image: linuxkit/openntpd:da26954c2f98a274091e5ed0bbdd2079a77a47c1
- name: nginx-ip-setup - name: nginx-ip-setup
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/sh", "-c", "ip a add 172.17.1.2/24 dev vethin-nginx; ip link set vethin-nginx up;" ] command: ["/bin/sh", "-c", "ip a add 172.17.1.2/24 dev vethin-nginx; ip link set vethin-nginx up;" ]
net: new net: new
runtime: runtime:
@ -55,7 +55,7 @@ onboot:
bindNS: bindNS:
net: /run/netns/nginx net: /run/netns/nginx
- name: frontal-ip-setup # without bonding - name: frontal-ip-setup # without bonding
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/sh", "-c", "ip link set name bond-frontal eth3; ip link set bond-frontal up; while read IP; do ip a add ${IP} dev bond-frontal; done < /run/config/ip_config/frontend-players; ip r add default via $(cat /run/config/ip_config/frontend-router); ip link add link bond-frontal name internet type vlan id 4; ip a add 10.10.10.2/29 dev internet; ip link set internet up;" ] command: ["/bin/sh", "-c", "ip link set name bond-frontal eth3; ip link set bond-frontal up; while read IP; do ip a add ${IP} dev bond-frontal; done < /run/config/ip_config/frontend-players; ip r add default via $(cat /run/config/ip_config/frontend-router); ip link add link bond-frontal name internet type vlan id 4; ip a add 10.10.10.2/29 dev internet; ip link set internet up;" ]
net: /run/netns/nginx net: /run/netns/nginx
binds: binds:
@ -67,7 +67,7 @@ onboot:
- name: eth3 - name: eth3
# - name: eth4 # - name: eth4
# - name: frontal-ip-setup # with bonding # - name: frontal-ip-setup # with bonding
# image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 # image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
# command: ["/bin/sh", "-c", "ip link set dev bond-frontal type bond mode balance-alb; ip link set bond-frontal up; ifenslave bond-frontal eth1 eth2 eth3 eth4; while read IP; do ip a add ${IP} dev bond-frontal; done < /run/config/ip_config/frontend-players; ip r add default via $(cat /run/config/ip_config/frontend-router); ip link add link bond-frontal name internet type vlan id 4; ip link set internet up; sysctl -w net.ipv4.ip_forward=1;" ] # command: ["/bin/sh", "-c", "ip link set dev bond-frontal type bond mode balance-alb; ip link set bond-frontal up; ifenslave bond-frontal eth1 eth2 eth3 eth4; while read IP; do ip a add ${IP} dev bond-frontal; done < /run/config/ip_config/frontend-players; ip r add default via $(cat /run/config/ip_config/frontend-router); ip link add link bond-frontal name internet type vlan id 4; ip link set internet up; sysctl -w net.ipv4.ip_forward=1;" ]
# net: /run/netns/nginx # net: /run/netns/nginx
# binds: # binds:
@ -81,7 +81,7 @@ onboot:
# - name: bond-frontal # - name: bond-frontal
# add: bond # add: bond
- name: receiver-ip-setup - name: receiver-ip-setup
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/sh", "-c", "ip a add 172.17.1.3/24 dev vethin-receiver; ip link set vethin-receiver up;" ] command: ["/bin/sh", "-c", "ip a add 172.17.1.3/24 dev vethin-receiver; ip link set vethin-receiver up;" ]
net: new net: new
runtime: runtime:
@ -92,7 +92,7 @@ onboot:
bindNS: bindNS:
net: /run/netns/fic-receiver net: /run/netns/fic-receiver
- name: sshd-ip-setup - name: sshd-ip-setup
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/sh", "-c", "ip a add 10.10.10.2/29 dev eth2; ip link set eth2 up;" ] command: ["/bin/sh", "-c", "ip a add 10.10.10.2/29 dev eth2; ip link set eth2 up;" ]
net: new net: new
runtime: runtime:
@ -101,7 +101,7 @@ onboot:
bindNS: bindNS:
net: /run/netns/sshd net: /run/netns/sshd
- name: auth-ip-setup - name: auth-ip-setup
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/sh", "-c", "ip a add 172.17.1.4/24 dev vethin-auth; ip link set vethin-auth up;" ] command: ["/bin/sh", "-c", "ip a add 172.17.1.4/24 dev vethin-auth; ip link set vethin-auth up;" ]
net: new net: new
runtime: runtime:
@ -112,7 +112,7 @@ onboot:
bindNS: bindNS:
net: /run/netns/auth net: /run/netns/auth
- name: bridge-setup - name: bridge-setup
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/sh", "-c", "ip a add 172.17.1.1/24 dev br0; ip link set veth-nginx master br0; ip link set veth-receiver master br0; ip link set veth-auth master br0; ip link set br0 up; ip link set veth-nginx up; ip link set veth-receiver up; ip link set veth-auth up;" ] command: ["/bin/sh", "-c", "ip a add 172.17.1.1/24 dev br0; ip link set veth-nginx master br0; ip link set veth-receiver master br0; ip link set veth-auth master br0; ip link set br0 up; ip link set veth-nginx up; ip link set veth-receiver up; ip link set veth-auth up;" ]
runtime: runtime:
interfaces: interfaces:
@ -120,7 +120,7 @@ onboot:
add: bridge add: bridge
- name: firewall-frontal - name: firewall-frontal
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/bash", "-c", "/sbin/iptables-restore < /etc/iptables/rules-frontal.v4; /sbin/ip6tables-restore < /etc/iptables/rules.v6; [ -f /run/config/remote_sync/destination ] && /sbin/iptables -I OUTPUT 7 -o bond-frontal -d $(cat /run/config/remote_sync/destination | tr -d '\n') -p tcp -m tcp --dport https -j ACCEPT;" ] command: ["/bin/bash", "-c", "/sbin/iptables-restore < /etc/iptables/rules-frontal.v4; /sbin/ip6tables-restore < /etc/iptables/rules.v6; [ -f /run/config/remote_sync/destination ] && /sbin/iptables -I OUTPUT 7 -o bond-frontal -d $(cat /run/config/remote_sync/destination | tr -d '\n') -p tcp -m tcp --dport https -j ACCEPT;" ]
binds: binds:
- /etc/iptables/rules-frontal.v4:/etc/iptables/rules-frontal.v4:ro - /etc/iptables/rules-frontal.v4:/etc/iptables/rules-frontal.v4:ro
@ -129,35 +129,26 @@ onboot:
- /run/config/remote_sync/:/run/config/remote_sync/:ro - /run/config/remote_sync/:/run/config/remote_sync/:ro
net: /run/netns/nginx net: /run/netns/nginx
- name: firewall-sshd - name: firewall-sshd
image: linuxkit/ip:9696394a7d57b384ae919662ae162c9152029156 image: linuxkit/ip:af77c3f93143ff352a07ad5233d25a665012bcce
command: ["/bin/bash", "-c", "/sbin/iptables-restore < /etc/iptables/rules-sshd.v4; /sbin/ip6tables-restore < /etc/iptables/rules.v6" ] command: ["/bin/bash", "-c", "/sbin/iptables-restore < /etc/iptables/rules-sshd.v4; /sbin/ip6tables-restore < /etc/iptables/rules.v6" ]
binds: binds:
- /etc/iptables/rules-sshd.v4:/etc/iptables/rules-sshd.v4:ro - /etc/iptables/rules-sshd.v4:/etc/iptables/rules-sshd.v4:ro
- /etc/iptables/rules.v6:/etc/iptables/rules.v6:ro - /etc/iptables/rules.v6:/etc/iptables/rules.v6:ro
net: /run/netns/sshd net: /run/netns/sshd
- name: create-ssh-keys
image: nemunaire/rsync:a3d76b2dd0a9ad73be44dc77ad765b20d96a3285
command: ["/bin/sh", "-c", "touch /etc/ssh/sshd_config && ssh-keygen -A"]
binds:
- /var/lib/fic/ssh:/etc/ssh
runtime:
mkdir:
- /var/lib/fic/ssh
services: services:
# - name: getty # - name: getty
# image: linuxkit/getty:05eca453695984a69617f1f1f0bcdae7f7032967 # image: linuxkit/getty:bae9e3d4861173bacf78f14a4fe44997a430d13b
# env: # env:
# - INSECURE=true # - INSECURE=true
# Enable acpi to shutdown on power events # Enable acpi to shutdown on power events
- name: acpid - name: acpid
image: linuxkit/acpid:6cb5575e487a8fcbd4c3eb6721c23299e6ea452f image: linuxkit/acpid:6379700e2f3341250432e37a4cac36e35c7caac8
- name: rngd - name: rngd
image: linuxkit/rngd:1a18f2149e42a0a1cb9e7d37608a494342c26032 image: linuxkit/rngd:814d1a3a76e84eae01a94575c038fd22652f94e3
- name: dhcpcd - name: dhcpcd
image: linuxkit/dhcpcd:157df9ef45a035f1542ec2270e374f18efef98a5 image: linuxkit/dhcpcd:330839488cd122db3c44738e265c035c9729a963
net: /run/netns/nginx net: /run/netns/nginx
binds: binds:
- /etc/dhcpcd.conf:/dhcpcd.conf:ro - /etc/dhcpcd.conf:/dhcpcd.conf:ro
@ -266,6 +257,7 @@ services:
- /var/lib/fic/files - /var/lib/fic/files
- /var/lib/fic/pki - /var/lib/fic/pki
- /var/lib/fic/settingsdist - /var/lib/fic/settingsdist
- /var/lib/fic/ssh
- /var/lib/fic/submissions - /var/lib/fic/submissions
- /var/lib/fic/teams - /var/lib/fic/teams
@ -288,7 +280,7 @@ services:
# net: /run/netns/nginx # net: /run/netns/nginx
- name: dexidp - name: dexidp
image: ghcr.io/dexidp/dex:v2.42.0 image: ghcr.io/dexidp/dex:v2.41.1
net: /run/netns/auth net: /run/netns/auth
binds: binds:
- /etc/hosts:/etc/hosts:ro - /etc/hosts:/etc/hosts:ro
@ -302,7 +294,7 @@ services:
mkdir: mkdir:
- /var/lib/fic/dex - /var/lib/fic/dex
- name: vouch-proxy - name: vouch-proxy
image: quay.io/vouch/vouch-proxy:alpine-0.41 image: quay.io/vouch/vouch-proxy:alpine-0.39
env: env:
- VOUCH_CONFIG=/etc/vouch/config.yml - VOUCH_CONFIG=/etc/vouch/config.yml
net: /run/netns/auth net: /run/netns/auth

View file

@ -1,15 +1,15 @@
kernel: kernel:
#image: nemunaire/kernel:5.10.62-0b705d955f5e283f62583c4e227d64a7924c138f-amd64 #image: nemunaire/kernel:5.10.62-0b705d955f5e283f62583c4e227d64a7924c138f-amd64
image: linuxkit/kernel:6.6.71 image: linuxkit/kernel:6.6.13
cmdline: "console=ttyS0 console=tty0" cmdline: "console=ttyS0 console=tty0"
init: init:
- nemunaire/mdadm:04814350d71ba9417e1f861be1685de26adf7a67 - nemunaire/mdadm:04814350d71ba9417e1f861be1685de26adf7a67
- nemunaire/syslinux:086f221f281d577d300949aa1094fb20c5cd90dc - nemunaire/syslinux:086f221f281d577d300949aa1094fb20c5cd90dc
- linuxkit/format:3fb088f60ed73ba4a15be41e44654b74112fd3f9 - linuxkit/format:3c858f0cf42a2b14441bfb5c266b78f14d2b75a4
- linuxkit/dm-crypt:981fde241bb84616a5ba94c04cdefa1489431a25 - linuxkit/dm-crypt:19fa6affe9da03afc91694e36d72a4924c65a0e0
- linuxkit/metadata:4f81c0c3a2b245567fd7d32d799018c9614a9907 - linuxkit/metadata:f35b5aafc7d19bb6a44a900840727902dad78e44
- alpine:latest - alpine:latest
files: files:

View file

@ -1,12 +1,12 @@
kernel: kernel:
#image: nemunaire/kernel:5.10.62-0b705d955f5e283f62583c4e227d64a7924c138f-amd64 #image: nemunaire/kernel:5.10.62-0b705d955f5e283f62583c4e227d64a7924c138f-amd64
image: linuxkit/kernel:6.6.71 image: linuxkit/kernel:6.6.13
cmdline: "console=ttyS0 console=tty0" cmdline: "console=ttyS0 console=tty0"
init: init:
- nemunaire/mdadm:04814350d71ba9417e1f861be1685de26adf7a67 - nemunaire/mdadm:04814350d71ba9417e1f861be1685de26adf7a67
- linuxkit/metadata:4f81c0c3a2b245567fd7d32d799018c9614a9907 - linuxkit/metadata:f35b5aafc7d19bb6a44a900840727902dad78e44
- alpine:latest - alpine:latest

File diff suppressed because it is too large Load diff

View file

@ -12,10 +12,10 @@
"@sveltejs/adapter-static": "^3.0.0", "@sveltejs/adapter-static": "^3.0.0",
"@sveltejs/kit": "^2.0.0", "@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0",
"@sveltestrap/sveltestrap": "^7.0.0", "@sveltestrap/sveltestrap": "^6.2.1",
"eslint": "^9.0.0", "eslint": "^9.0.0",
"eslint-config-prettier": "^10.0.0", "eslint-config-prettier": "^9.0.0",
"eslint-plugin-svelte": "^3.0.0", "eslint-plugin-svelte": "^2.35.1",
"prettier": "^3.0.0", "prettier": "^3.0.0",
"prettier-plugin-svelte": "^3.1.2", "prettier-plugin-svelte": "^3.1.2",
"sass": "^1.51.0", "sass": "^1.51.0",

View file

@ -33,9 +33,9 @@
</h1> </h1>
<div style="min-width: 0"> <div style="min-width: 0">
<h4 class="fw-bold"><samp>{file.name}</samp></h4> <h4 class="fw-bold"><samp>{file.name}</samp></h4>
{#if file.disclaimer} {#if file.disclamer}
<div class="file-disclaimer text-warning"> <div class="file-disclamer text-warning">
{file.disclaimer} {file.disclamer}
</div> </div>
{/if} {/if}
<nobr> <nobr>
@ -61,10 +61,10 @@
{/if} {/if}
<style> <style>
.file-disclaimer { .file-disclamer {
display: none; display: none;
} }
:global(.list-group-item:hover .file-disclaimer) { :global(.list-group-item:hover .file-disclamer) {
display: block; display: block;
} }
</style> </style>

42
go.mod
View file

@ -1,16 +1,16 @@
module srs.epita.fr/fic-server module srs.epita.fr/fic-server
go 1.23.0 go 1.21
toolchain go1.24.1 toolchain go1.23.4
require ( require (
github.com/BurntSushi/toml v1.5.0 github.com/BurntSushi/toml v1.4.0
github.com/asticode/go-astisub v0.34.0 github.com/asticode/go-astisub v0.32.0
github.com/cenkalti/dominantcolor v1.0.3 github.com/cenkalti/dominantcolor v1.0.3
github.com/gin-contrib/sessions v1.0.2 github.com/gin-contrib/sessions v1.0.2
github.com/gin-gonic/gin v1.10.0 github.com/gin-gonic/gin v1.10.0
github.com/go-git/go-git/v5 v5.14.0 github.com/go-git/go-git/v5 v5.13.1
github.com/go-sql-driver/mysql v1.8.1 github.com/go-sql-driver/mysql v1.8.1
github.com/google/gopacket v1.1.19 github.com/google/gopacket v1.1.19
github.com/studio-b12/gowebdav v0.10.0 github.com/studio-b12/gowebdav v0.10.0
@ -18,17 +18,17 @@ require (
github.com/yuin/goldmark v1.7.8 github.com/yuin/goldmark v1.7.8
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b
go.uber.org/multierr v1.11.0 go.uber.org/multierr v1.11.0
golang.org/x/crypto v0.36.0 golang.org/x/crypto v0.31.0
golang.org/x/image v0.25.0 golang.org/x/image v0.23.0
golang.org/x/oauth2 v0.28.0 golang.org/x/oauth2 v0.25.0
gopkg.in/fsnotify.v1 v1.4.7 gopkg.in/fsnotify.v1 v1.4.7
) )
require ( require (
dario.cat/mergo v1.0.0 // indirect dario.cat/mergo v1.0.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ProtonMail/go-crypto v1.1.5 // indirect github.com/ProtonMail/go-crypto v1.1.3 // indirect
github.com/acomagu/bufpipe v1.0.4 // indirect github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/asticode/go-astikit v0.20.0 // indirect github.com/asticode/go-astikit v0.20.0 // indirect
github.com/asticode/go-astits v1.8.0 // indirect github.com/asticode/go-astits v1.8.0 // indirect
@ -37,23 +37,23 @@ require (
github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.1 // indirect github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/cloudflare/circl v1.6.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect github.com/cloudwego/iasm v0.2.0 // indirect
github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/cyphar/filepath-securejoin v0.3.6 // indirect
github.com/disintegration/imaging v1.6.2 // indirect github.com/disintegration/imaging v1.6.2 // indirect
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/go-git/go-billy/v5 v5.6.1 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.20.0 // indirect github.com/go-playground/validator/v10 v10.20.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect github.com/goccy/go-json v0.10.2 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/gorilla/context v1.1.2 // indirect github.com/gorilla/context v1.1.2 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect
github.com/gorilla/sessions v1.2.2 // indirect github.com/gorilla/sessions v1.2.2 // indirect
@ -69,20 +69,20 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pjbgf/sha1cd v0.3.2 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect github.com/skeema/knownhosts v1.3.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/u2takey/go-utils v0.3.1 // indirect github.com/u2takey/go-utils v0.3.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect github.com/ugorji/go/codec v1.2.12 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect
golang.org/x/arch v0.8.0 // indirect golang.org/x/arch v0.8.0 // indirect
golang.org/x/mod v0.17.0 // indirect golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.35.0 // indirect golang.org/x/net v0.33.0 // indirect
golang.org/x/sync v0.12.0 // indirect golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.31.0 // indirect golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.23.0 // indirect golang.org/x/text v0.21.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.34.1 // indirect google.golang.org/protobuf v1.34.1 // indirect

57
go.sum
View file

@ -10,8 +10,6 @@ github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
@ -19,8 +17,6 @@ github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VM
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I= github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I=
@ -37,8 +33,6 @@ github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0k
github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk= github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk=
github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4=
github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
@ -74,8 +68,6 @@ github.com/asticode/go-astisub v0.30.0 h1:z4k2Y+V+rlCE8qk3uw/nie56KXxJaL1/GwTP+9
github.com/asticode/go-astisub v0.30.0/go.mod h1:WTkuSzFB+Bp7wezuSf2Oxulj5A8zu2zLRVFf6bIFQK8= github.com/asticode/go-astisub v0.30.0/go.mod h1:WTkuSzFB+Bp7wezuSf2Oxulj5A8zu2zLRVFf6bIFQK8=
github.com/asticode/go-astisub v0.32.0 h1:i1RHVQyTxSAuX0X3YC5zIyWruVZorS3cDXxqxYa0qss= github.com/asticode/go-astisub v0.32.0 h1:i1RHVQyTxSAuX0X3YC5zIyWruVZorS3cDXxqxYa0qss=
github.com/asticode/go-astisub v0.32.0/go.mod h1:WTkuSzFB+Bp7wezuSf2Oxulj5A8zu2zLRVFf6bIFQK8= github.com/asticode/go-astisub v0.32.0/go.mod h1:WTkuSzFB+Bp7wezuSf2Oxulj5A8zu2zLRVFf6bIFQK8=
github.com/asticode/go-astisub v0.34.0 h1:owKNj0A9pc7YVW/rNy2MJZ1mf0L8DTdklZVfyZDhTWI=
github.com/asticode/go-astisub v0.34.0/go.mod h1:WTkuSzFB+Bp7wezuSf2Oxulj5A8zu2zLRVFf6bIFQK8=
github.com/asticode/go-astits v1.8.0 h1:rf6aiiGn/QhlFjNON1n5plqF3Fs025XLUwiQ0NB6oZg= github.com/asticode/go-astits v1.8.0 h1:rf6aiiGn/QhlFjNON1n5plqF3Fs025XLUwiQ0NB6oZg=
github.com/asticode/go-astits v1.8.0/go.mod h1:DkOWmBNQpnr9mv24KfZjq4JawCFX1FCqjLVGvO0DygQ= github.com/asticode/go-astits v1.8.0/go.mod h1:DkOWmBNQpnr9mv24KfZjq4JawCFX1FCqjLVGvO0DygQ=
github.com/aws/aws-sdk-go v1.38.20 h1:QbzNx/tdfATbdKfubBpkt84OM6oBkxQZRw6+bW2GyeA= github.com/aws/aws-sdk-go v1.38.20 h1:QbzNx/tdfATbdKfubBpkt84OM6oBkxQZRw6+bW2GyeA=
@ -112,8 +104,6 @@ github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEM
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk=
github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
@ -123,8 +113,6 @@ github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53E
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM=
github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -180,8 +168,6 @@ github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA= github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA=
github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE= github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE=
github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8= github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8=
github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
@ -213,10 +199,6 @@ github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZt
github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY=
github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M= github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M=
github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc= github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc=
github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0=
github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A=
github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60=
github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
@ -261,15 +243,12 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
@ -373,8 +352,6 @@ github.com/pjbgf/sha1cd v0.2.3 h1:uKQP/7QOzNtKYH7UTohZLcjF5/55EnTw0jO/Ru4jZwI=
github.com/pjbgf/sha1cd v0.2.3/go.mod h1:HOK9QrgzdHpbc2Kzip0Q1yi3M2MFGPADtR6HjG65m5M= github.com/pjbgf/sha1cd v0.2.3/go.mod h1:HOK9QrgzdHpbc2Kzip0Q1yi3M2MFGPADtR6HjG65m5M=
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -405,8 +382,6 @@ github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L
github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -567,12 +542,6 @@ golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.1.0 h1:r8Oj8ZA2Xy12/b5KZYj3tuv7NG/fBz3TwQVvpJ9l8Rk= golang.org/x/image v0.1.0 h1:r8Oj8ZA2Xy12/b5KZYj3tuv7NG/fBz3TwQVvpJ9l8Rk=
golang.org/x/image v0.1.0/go.mod h1:iyPr49SD/G/TBxYVB/9RRtGUT5eNbo2u4NamWeQcD5c= golang.org/x/image v0.1.0/go.mod h1:iyPr49SD/G/TBxYVB/9RRtGUT5eNbo2u4NamWeQcD5c=
@ -620,10 +589,6 @@ golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g=
golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4= golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4=
golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68=
golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY= golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY=
golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8=
golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ=
golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@ -692,10 +657,6 @@ golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y=
golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A=
golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU= golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU=
@ -746,10 +707,6 @@ golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -761,10 +718,6 @@ golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -845,12 +798,6 @@ golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -900,10 +847,6 @@ golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View file

@ -1,26 +0,0 @@
package fic
import ()
type CyberrangeAPIResponse struct {
Data interface{}
CurrentPage int `json:"current_page"`
PerPage int `json:"per_page"`
LastPage int `json:"last_page"`
Total int `json:"total"`
}
type CyberrangeTeam struct {
UUID string `json:"session_uuid"`
Members []CyberrangeTeamMember `json:"members"`
Name string `json:"name"`
Score int64 `json:"score"`
Rank int `json:"rank"`
}
type CyberrangeTeamMember struct {
UUID string `json:"session_uuid"`
Name string `json:"name"`
Nickname string `json:"nickname"`
EMail string `json:"email"`
}

View file

@ -414,7 +414,6 @@ CREATE TABLE IF NOT EXISTS exercice_solved(
} }
if _, err := db.Exec(` if _, err := db.Exec(`
CREATE TABLE IF NOT EXISTS exercice_tries( CREATE TABLE IF NOT EXISTS exercice_tries(
id_try INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
id_exercice INTEGER NOT NULL, id_exercice INTEGER NOT NULL,
id_team INTEGER NOT NULL, id_team INTEGER NOT NULL,
time TIMESTAMP NOT NULL, time TIMESTAMP NOT NULL,
@ -424,26 +423,6 @@ CREATE TABLE IF NOT EXISTS exercice_tries(
FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice), FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice),
FOREIGN KEY(id_team) REFERENCES teams(id_team) FOREIGN KEY(id_team) REFERENCES teams(id_team)
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; ) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
`); err != nil {
return err
}
if _, err := db.Exec(`
CREATE TABLE IF NOT EXISTS exercice_tries_flags(
id_try INTEGER NOT NULL,
id_flag INTEGER NOT NULL,
FOREIGN KEY(id_try) REFERENCES exercice_tries(id_try) ON DELETE CASCADE,
FOREIGN KEY(id_flag) REFERENCES exercice_flags(id_flag) ON DELETE CASCADE
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
`); err != nil {
return err
}
if _, err := db.Exec(`
CREATE TABLE IF NOT EXISTS exercice_tries_mcq(
id_try INTEGER NOT NULL,
id_mcq INTEGER NOT NULL,
FOREIGN KEY(id_try) REFERENCES exercice_tries(id_try) ON DELETE CASCADE,
FOREIGN KEY(id_mcq) REFERENCES exercice_mcq(id_mcq) ON DELETE CASCADE
) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
`); err != nil { `); err != nil {
return err return err
} }

View file

@ -3,7 +3,6 @@ package fic
import ( import (
"errors" "errors"
"fmt" "fmt"
"log"
"math" "math"
"time" "time"
) )
@ -445,25 +444,11 @@ func (e *Exercice) GetOrdinal() (int, error) {
} }
// NewTry registers a solving attempt for the given Team. // NewTry registers a solving attempt for the given Team.
func (e *Exercice) NewTry(t *Team, cksum []byte, flags ...Flag) (int64, error) { func (e *Exercice) NewTry(t *Team, cksum []byte) error {
if res, err := DBExec("INSERT INTO exercice_tries (id_exercice, id_team, time, cksum) VALUES (?, ?, ?, ?)", e.Id, t.Id, time.Now(), cksum); err != nil { if _, err := DBExec("INSERT INTO exercice_tries (id_exercice, id_team, time, cksum) VALUES (?, ?, ?, ?)", e.Id, t.Id, time.Now(), cksum); err != nil {
return 0, err return err
} else { } else {
return res.LastInsertId() return nil
}
}
func (e *Exercice) NewTryFlag(tryid int64, flags ...Flag) {
for _, flag := range flags {
if fk, ok := flag.(*FlagKey); ok {
if _, err := DBExec("INSERT INTO exercice_tries_flags (id_try, id_flag) VALUES (?, ?)", tryid, fk.Id); err != nil {
log.Println("Unable to add detailed try: ", err.Error())
}
} else if fm, ok := flag.(*MCQ); ok {
if _, err := DBExec("INSERT INTO exercice_tries_mcq (id_try, id_mcq) VALUES (?, ?)", tryid, fm.Id); err != nil {
log.Println("Unable to add detailed try: ", err.Error())
}
}
} }
} }
@ -565,7 +550,7 @@ func (e *Exercice) MCQSolved() (res []int64) {
// CheckResponse, given both flags and MCQ responses, figures out if thoses are correct (or if they are previously solved). // CheckResponse, given both flags and MCQ responses, figures out if thoses are correct (or if they are previously solved).
// In the meanwhile, CheckResponse registers good answers given (but it does not mark the challenge as solved at the end). // In the meanwhile, CheckResponse registers good answers given (but it does not mark the challenge as solved at the end).
func (e *Exercice) CheckResponse(cksum []byte, respflags map[int]string, respmcq map[int]bool, t *Team) (bool, error) { func (e *Exercice) CheckResponse(cksum []byte, respflags map[int]string, respmcq map[int]bool, t *Team) (bool, error) {
if tryId, err := e.NewTry(t, cksum); err != nil { if err := e.NewTry(t, cksum); err != nil {
return false, err return false, err
} else if flags, err := e.GetFlagKeys(); err != nil { } else if flags, err := e.GetFlagKeys(); err != nil {
return false, err return false, err
@ -580,10 +565,6 @@ func (e *Exercice) CheckResponse(cksum []byte, respflags map[int]string, respmcq
// Check MCQs // Check MCQs
for _, mcq := range mcqs { for _, mcq := range mcqs {
if mcq.HasOneEntry(respmcq) {
e.NewTryFlag(tryId, mcq)
}
if d := mcq.Check(respmcq); d > 0 { if d := mcq.Check(respmcq); d > 0 {
if !PartialValidation || t.HasPartiallySolved(mcq) == nil { if !PartialValidation || t.HasPartiallySolved(mcq) == nil {
valid = false valid = false
@ -608,21 +589,15 @@ func (e *Exercice) CheckResponse(cksum []byte, respflags map[int]string, respmcq
for _, flag := range flags { for _, flag := range flags {
if res, ok := respflags[flag.Id]; !ok && (!PartialValidation || t.HasPartiallySolved(flag) == nil) { if res, ok := respflags[flag.Id]; !ok && (!PartialValidation || t.HasPartiallySolved(flag) == nil) {
valid = valid && flag.IsOptionnal() valid = valid && flag.IsOptionnal()
} else if ok { } else if flag.Check([]byte(res)) != 0 {
if len(res) > 0 { if !PartialValidation || t.HasPartiallySolved(flag) == nil {
e.NewTryFlag(tryId, flag) valid = valid && flag.IsOptionnal()
} }
} else {
if flag.Check([]byte(res)) != 0 { err := flag.FoundBy(t)
if !PartialValidation || t.HasPartiallySolved(flag) == nil { if err == nil {
valid = valid && flag.IsOptionnal() // err is unicity issue, probably flag already found
} goodResponses += 1
} else {
err := flag.FoundBy(t)
if err == nil {
// err is unicity issue, probably flag already found
goodResponses += 1
}
} }
} }
} }

View file

@ -68,8 +68,7 @@ func (e *Exercice) AppendHistoryItem(tId int64, kind string, secondary *int64) e
if kind == "tries" { if kind == "tries" {
bid := make([]byte, 5) bid := make([]byte, 5)
binary.LittleEndian.PutUint32(bid, rand.Uint32()) binary.LittleEndian.PutUint32(bid, rand.Uint32())
_, err = (&Exercice{Id: e.Id}).NewTry(team, bid) return (&Exercice{Id: e.Id}).NewTry(team, bid)
return err
} else if kind == "hint" && secondary != nil { } else if kind == "hint" && secondary != nil {
return team.OpenHint(&EHint{Id: *secondary}) return team.OpenHint(&EHint{Id: *secondary})
} else if kind == "wchoices" && secondary != nil { } else if kind == "wchoices" && secondary != nil {

View file

@ -392,12 +392,7 @@ func (f *EFile) GetDepends() ([]Flag, error) {
// CheckFileOnDisk recalculates the hash of the file on disk. // CheckFileOnDisk recalculates the hash of the file on disk.
func (f *EFile) CheckFileOnDisk() error { func (f *EFile) CheckFileOnDisk() error {
firstChecksum := f.Checksum if _, size, err := checkFileHash(path.Join(FilesDir, f.Path), f.Checksum); err != nil {
if len(f.ChecksumShown) > 0 {
firstChecksum = f.ChecksumShown
}
if _, size, err := checkFileHash(path.Join(FilesDir, f.Path), firstChecksum); size > 0 && err != nil {
return err return err
} else if size == 0 { } else if size == 0 {
if _, _, err := checkFileHash(path.Join(FilesDir, f.Path+".gz"), f.Checksum); err != nil { if _, _, err := checkFileHash(path.Join(FilesDir, f.Path+".gz"), f.Checksum); err != nil {
@ -405,17 +400,9 @@ func (f *EFile) CheckFileOnDisk() error {
} else { } else {
return nil return nil
} }
} else if err != nil { } else {
return err return nil
} }
if _, err := os.Stat(path.Join(FilesDir, f.Path+".gz")); !os.IsNotExist(err) {
if _, _, err = checkFileHash(path.Join(FilesDir, f.Path+".gz"), f.Checksum); err != nil {
return err
}
}
return nil
} }
// GunzipFileOnDisk gunzip a compressed file. // GunzipFileOnDisk gunzip a compressed file.

View file

@ -14,9 +14,6 @@ type Flag interface {
Check(val interface{}) int Check(val interface{}) int
IsOptionnal() bool IsOptionnal() bool
FoundBy(t *Team) error FoundBy(t *Team) error
NbTries() (int64, error)
TeamsOnIt() ([]int64, error)
DeleteTries() error
} }
// GetFlag returns a list of flags comming with the challenge. // GetFlag returns a list of flags comming with the challenge.

View file

@ -230,54 +230,6 @@ func (k *FlagKey) RecoverId() (Flag, error) {
} }
} }
// NbTries returns the flag resolution statistics.
func (k *FlagKey) NbTries() (tries int64, err error) {
err = DBQueryRow("SELECT COUNT(*) AS tries FROM exercice_tries_flags WHERE id_flag = ?", k.Id).Scan(&tries)
return
}
func (k *FlagKey) TeamsOnIt() ([]int64, error) {
if rows, err := DBQuery("SELECT DISTINCT M.id_team FROM exercice_tries_flags F INNER JOIN exercice_tries T ON T.id_try = F.id_try INNER JOIN teams M ON M.id_team = T.id_team WHERE id_flag = ?", k.Id); err != nil {
return nil, err
} else {
defer rows.Close()
teams := []int64{}
for rows.Next() {
var idteam int64
if err := rows.Scan(&idteam); err != nil {
return nil, err
}
teams = append(teams, idteam)
}
return teams, nil
}
}
func (k *FlagKey) DeleteTries() error {
if rows, err := DBQuery("SELECT id_try FROM exercice_tries_flags WHERE id_flag = ?", k.Id); err != nil {
return err
} else {
defer rows.Close()
for rows.Next() {
var idtry int64
err = rows.Scan(&idtry)
if err != nil {
return err
}
_, err = DBExec("DELETE FROM exercice_tries WHERE id_try = ?", idtry)
if err != nil {
return err
}
}
return nil
}
}
// AddFlagKey creates and fills a new struct Flag, from a hashed flag, and registers it into the database. // AddFlagKey creates and fills a new struct Flag, from a hashed flag, and registers it into the database.
func (k *FlagKey) Create(e *Exercice) (Flag, error) { func (k *FlagKey) Create(e *Exercice) (Flag, error) {
// Check the regexp compile // Check the regexp compile

View file

@ -71,18 +71,6 @@ func (k *FlagLabel) RecoverId() (Flag, error) {
} }
} }
func (k *FlagLabel) NbTries() (int64, error) {
return 0, nil
}
func (k *FlagLabel) TeamsOnIt() ([]int64, error) {
return nil, nil
}
func (k *FlagLabel) DeleteTries() error {
return nil
}
// AddFlagLabel creates and fills a new struct Flag and registers it into the database. // AddFlagLabel creates and fills a new struct Flag and registers it into the database.
func (k *FlagLabel) Create(e *Exercice) (Flag, error) { func (k *FlagLabel) Create(e *Exercice) (Flag, error) {
if res, err := DBExec("INSERT INTO exercice_flag_labels (id_exercice, ordre, label, variant) VALUES (?, ?, ?, ?)", e.Id, k.Order, k.Label, k.Variant); err != nil { if res, err := DBExec("INSERT INTO exercice_flag_labels (id_exercice, ordre, label, variant) VALUES (?, ?, ?, ?)", e.Id, k.Order, k.Label, k.Variant); err != nil {

View file

@ -136,54 +136,6 @@ func (m *MCQ) RecoverId() (Flag, error) {
} }
} }
// NbTries returns the MCQ resolution statistics.
func (m *MCQ) NbTries() (tries int64, err error) {
err = DBQueryRow("SELECT COUNT(*) AS tries FROM exercice_tries_mcq WHERE id_mcq = ?", m.Id).Scan(&tries)
return
}
func (m *MCQ) TeamsOnIt() ([]int64, error) {
if rows, err := DBQuery("SELECT DISTINCT M.id_team FROM exercice_tries_mcq F INNER JOIN exercice_tries T ON T.id_try = F.id_try INNER JOIN teams M ON M.id_team = T.id_team WHERE id_mcq = ?", m.Id); err != nil {
return nil, err
} else {
defer rows.Close()
teams := []int64{}
for rows.Next() {
var idteam int64
if err := rows.Scan(&idteam); err != nil {
return nil, err
}
teams = append(teams, idteam)
}
return teams, nil
}
}
func (m *MCQ) DeleteTries() error {
if rows, err := DBQuery("SELECT id_try FROM exercice_tries_mcq WHERE id_mcq = ?", m.Id); err != nil {
return err
} else {
defer rows.Close()
for rows.Next() {
var idtry int64
err = rows.Scan(&idtry)
if err != nil {
return err
}
_, err = DBExec("DELETE FROM exercice_tries WHERE id_try = ?", idtry)
if err != nil {
return err
}
}
return nil
}
}
// Create registers a MCQ into the database and recursively add its entries. // Create registers a MCQ into the database and recursively add its entries.
func (m *MCQ) Create(e *Exercice) (Flag, error) { func (m *MCQ) Create(e *Exercice) (Flag, error) {
if res, err := DBExec("INSERT INTO exercice_mcq (id_exercice, ordre, title) VALUES (?, ?, ?)", e.Id, m.Order, m.Title); err != nil { if res, err := DBExec("INSERT INTO exercice_mcq (id_exercice, ordre, title) VALUES (?, ?, ?)", e.Id, m.Order, m.Title); err != nil {
@ -255,7 +207,7 @@ func (m *MCQ) AddEntry(e *MCQ_entry) (*MCQ_entry, error) {
// Update applies modifications back to the database. // Update applies modifications back to the database.
func (n *MCQ_entry) Update() (int64, error) { func (n *MCQ_entry) Update() (int64, error) {
if res, err := DBExec("UPDATE mcq_entries SET label = ?, response = ? WHERE id_mcq_entry = ?", n.Label, n.Response, n.Id); err != nil { if res, err := DBExec("UPDATE mcq_entries SET label = ?, response = ? WHERE id_mcq = ?", n.Label, n.Response, n.Id); err != nil {
return 0, err return 0, err
} else if nb, err := res.RowsAffected(); err != nil { } else if nb, err := res.RowsAffected(); err != nil {
return 0, err return 0, err
@ -367,24 +319,6 @@ func (m *MCQ) IsOptionnal() bool {
return false return false
} }
// Check if the given vals contains at least a response for the given MCQ.
func (m *MCQ) HasOneEntry(v interface{}) bool {
var vals map[int]bool
if va, ok := v.(map[int]bool); !ok {
return false
} else {
vals = va
}
for _, n := range m.Entries {
if _, ok := vals[n.Id]; ok {
return true
}
}
return false
}
// Check if the given vals are the expected ones to validate this flag. // Check if the given vals are the expected ones to validate this flag.
func (m *MCQ) Check(v interface{}) int { func (m *MCQ) Check(v interface{}) int {
var vals map[int]bool var vals map[int]bool

View file

@ -3,7 +3,6 @@ package fic
import ( import (
"bytes" "bytes"
"crypto/md5" "crypto/md5"
"math/rand"
"regexp" "regexp"
"strings" "strings"
) )
@ -188,11 +187,3 @@ func (c HSL) ToRGB() (rgb uint32) {
return r*65536 + g*256 + b return r*65536 + g*256 + b
} }
func RandomColor() HSL {
return HSL{
H: rand.Float64(),
S: 1,
L: 0.5,
}
}

480
qa/ui/package-lock.json generated
View file

@ -8,7 +8,7 @@
"name": "qa", "name": "qa",
"version": "0.0.1", "version": "0.0.1",
"dependencies": { "dependencies": {
"@sveltestrap/sveltestrap": "^7.0.0", "@sveltestrap/sveltestrap": "^6.2.1",
"bootstrap": "^5.2.2", "bootstrap": "^5.2.2",
"bootstrap-icons": "^1.9.1" "bootstrap-icons": "^1.9.1"
}, },
@ -17,8 +17,8 @@
"@sveltejs/kit": "^2.0.0", "@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0",
"eslint": "^9.0.0", "eslint": "^9.0.0",
"eslint-config-prettier": "^10.0.0", "eslint-config-prettier": "^9.0.0",
"eslint-plugin-svelte": "^3.0.0", "eslint-plugin-svelte": "^2.35.1",
"prettier": "^3.0.0", "prettier": "^3.0.0",
"prettier-plugin-svelte": "^3.1.2", "prettier-plugin-svelte": "^3.1.2",
"svelte": "^5.0.0", "svelte": "^5.0.0",
@ -472,13 +472,13 @@
} }
}, },
"node_modules/@eslint/config-array": { "node_modules/@eslint/config-array": {
"version": "0.19.2", "version": "0.19.1",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz",
"integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@eslint/object-schema": "^2.1.6", "@eslint/object-schema": "^2.1.5",
"debug": "^4.3.1", "debug": "^4.3.1",
"minimatch": "^3.1.2" "minimatch": "^3.1.2"
}, },
@ -486,20 +486,10 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
} }
}, },
"node_modules/@eslint/config-helpers": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.0.tgz",
"integrity": "sha512-yJLLmLexii32mGrhW29qvU3QBVTu0GUmEf/J4XsBtVhp4JkIUFN/BjWqTF63yRvGApIDpZm5fa97LtYtINmfeQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/core": { "node_modules/@eslint/core": {
"version": "0.12.0", "version": "0.10.0",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz",
"integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
@ -510,9 +500,9 @@
} }
}, },
"node_modules/@eslint/eslintrc": { "node_modules/@eslint/eslintrc": {
"version": "3.3.1", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz",
"integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -534,9 +524,9 @@
} }
}, },
"node_modules/@eslint/js": { "node_modules/@eslint/js": {
"version": "9.23.0", "version": "9.18.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz",
"integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -544,9 +534,9 @@
} }
}, },
"node_modules/@eslint/object-schema": { "node_modules/@eslint/object-schema": {
"version": "2.1.6", "version": "2.1.5",
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz",
"integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"engines": { "engines": {
@ -554,13 +544,13 @@
} }
}, },
"node_modules/@eslint/plugin-kit": { "node_modules/@eslint/plugin-kit": {
"version": "0.2.7", "version": "0.2.5",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz",
"integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@eslint/core": "^0.12.0", "@eslint/core": "^0.10.0",
"levn": "^0.4.1" "levn": "^0.4.1"
}, },
"engines": { "engines": {
@ -620,9 +610,9 @@
} }
}, },
"node_modules/@humanwhocodes/retry": { "node_modules/@humanwhocodes/retry": {
"version": "0.4.2", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz",
"integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"engines": { "engines": {
@ -699,9 +689,9 @@
} }
}, },
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz",
"integrity": "sha512-G2fUQQANtBPsNwiVFg4zKiPQyjVKZCUdQUol53R8E71J7AsheRMV/Yv/nB8giOcOVqP7//eB5xPqieBYZe9bGg==", "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -713,9 +703,9 @@
] ]
}, },
"node_modules/@rollup/rollup-android-arm64": { "node_modules/@rollup/rollup-android-arm64": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz",
"integrity": "sha512-qhFwQ+ljoymC+j5lXRv8DlaJYY/+8vyvYmVx074zrLsu5ZGWYsJNLjPPVJJjhZQpyAKUGPydOq9hRLLNvh1s3A==", "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -727,9 +717,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-arm64": { "node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz",
"integrity": "sha512-44n/X3lAlWsEY6vF8CzgCx+LQaoqWGN7TzUfbJDiTIOjJm4+L2Yq+r5a8ytQRGyPqgJDs3Rgyo8eVL7n9iW6AQ==", "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -741,9 +731,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-x64": { "node_modules/@rollup/rollup-darwin-x64": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz",
"integrity": "sha512-F9ct0+ZX5Np6+ZDztxiGCIvlCaW87HBdHcozUfsHnj1WCUTBUubAoanhHUfnUHZABlElyRikI0mgcw/qdEm2VQ==", "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -755,9 +745,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-arm64": { "node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz",
"integrity": "sha512-JpsGxLBB2EFXBsTLHfkZDsXSpSmKD3VxXCgBQtlPcuAqB8TlqtLcbeMhxXQkCDv1avgwNjF8uEIbq5p+Cee0PA==", "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -769,9 +759,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-x64": { "node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz",
"integrity": "sha512-wegiyBT6rawdpvnD9lmbOpx5Sph+yVZKHbhnSP9MqUEDX08G4UzMU+D87jrazGE7lRSyTRs6NEYHtzfkJ3FjjQ==", "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -783,9 +773,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-gnueabihf": { "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz",
"integrity": "sha512-3pA7xecItbgOs1A5H58dDvOUEboG5UfpTq3WzAdF54acBbUM+olDJAPkgj1GRJ4ZqE12DZ9/hNS2QZk166v92A==", "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -797,9 +787,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-musleabihf": { "node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz",
"integrity": "sha512-Y7XUZEVISGyge51QbYyYAEHwpGgmRrAxQXO3siyYo2kmaj72USSG8LtlQQgAtlGfxYiOwu+2BdbPjzEpcOpRmQ==", "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -811,9 +801,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-gnu": { "node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz",
"integrity": "sha512-r7/OTF5MqeBrZo5omPXcTnjvv1GsrdH8a8RerARvDFiDwFpDVDnJyByYM/nX+mvks8XXsgPUxkwe/ltaX2VH7w==", "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -825,9 +815,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-musl": { "node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz",
"integrity": "sha512-HJbifC9vex9NqnlodV2BHVFNuzKL5OnsV2dvTw6e1dpZKkNjPG6WUq+nhEYV6Hv2Bv++BXkwcyoGlXnPrjAKXw==", "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -839,9 +829,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-loongarch64-gnu": { "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz",
"integrity": "sha512-VAEzZTD63YglFlWwRj3taofmkV1V3xhebDXffon7msNz4b14xKsz7utO6F8F4cqt8K/ktTl9rm88yryvDpsfOw==", "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@ -853,9 +843,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": { "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz",
"integrity": "sha512-Sts5DST1jXAc9YH/iik1C9QRsLcCoOScf3dfbY5i4kH9RJpKxiTBXqm7qU5O6zTXBTEZry69bGszr3SMgYmMcQ==", "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@ -867,9 +857,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-gnu": { "node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz",
"integrity": "sha512-qhlXeV9AqxIyY9/R1h1hBD6eMvQCO34ZmdYvry/K+/MBs6d1nRFLm6BOiITLVI+nFAAB9kUB6sdJRKyVHXnqZw==", "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@ -881,9 +871,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-s390x-gnu": { "node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz",
"integrity": "sha512-8ZGN7ExnV0qjXa155Rsfi6H8M4iBBwNLBM9lcVS+4NcSzOFaNqmt7djlox8pN1lWrRPMRRQ8NeDlozIGx3Omsw==", "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@ -895,9 +885,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-gnu": { "node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz",
"integrity": "sha512-VDzNHtLLI5s7xd/VubyS10mq6TxvZBp+4NRWoW+Hi3tgV05RtVm4qK99+dClwTN1McA6PHwob6DEJ6PlXbY83A==", "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -909,9 +899,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-musl": { "node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz",
"integrity": "sha512-qcb9qYDlkxz9DxJo7SDhWxTWV1gFuwznjbTiov289pASxlfGbaOD54mgbs9+z94VwrXtKTu+2RqwlSTbiOqxGg==", "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -923,9 +913,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-arm64-msvc": { "node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz",
"integrity": "sha512-pFDdotFDMXW2AXVbfdUEfidPAk/OtwE/Hd4eYMTNVVaCQ6Yl8et0meDaKNL63L44Haxv4UExpv9ydSf3aSayDg==", "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -937,9 +927,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-ia32-msvc": { "node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz",
"integrity": "sha512-/TG7WfrCAjeRNDvI4+0AAMoHxea/USWhAzf9PVDFHbcqrQ7hMMKp4jZIy4VEjk72AAfN5k4TiSMRXRKf/0akSw==", "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -951,9 +941,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-msvc": { "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.32.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz",
"integrity": "sha512-5hqO5S3PTEO2E5VjCePxv40gIgyS2KvO7E7/vvC/NbIW4SIRamkMr1hqj+5Y67fbBWv/bQLB6KelBQmXlyCjWA==", "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -964,15 +954,6 @@
"win32" "win32"
] ]
}, },
"node_modules/@sveltejs/acorn-typescript": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz",
"integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==",
"license": "MIT",
"peerDependencies": {
"acorn": "^8.9.0"
}
},
"node_modules/@sveltejs/adapter-static": { "node_modules/@sveltejs/adapter-static": {
"version": "3.0.8", "version": "3.0.8",
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.8.tgz", "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.8.tgz",
@ -984,23 +965,25 @@
} }
}, },
"node_modules/@sveltejs/kit": { "node_modules/@sveltejs/kit": {
"version": "2.20.2", "version": "2.15.2",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.20.2.tgz", "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.15.2.tgz",
"integrity": "sha512-Dv8TOAZC9vyfcAB9TMsvUEJsRbklRTeNfcYBPaeH6KnABJ99i3CvCB2eNx8fiiliIqe+9GIchBg4RodRH5p1BQ==", "integrity": "sha512-p208T1kdM6zd8k4YXIUM60pLWQ8dZqehXSiqn4NulXHyHibX53uIAL2xtNL8GjxX2IVPqPRT978MwVYhCKExdQ==",
"dev": true, "dev": true,
"hasInstallScript": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@types/cookie": "^0.6.0", "@types/cookie": "^0.6.0",
"cookie": "^0.6.0", "cookie": "^0.6.0",
"devalue": "^5.1.0", "devalue": "^5.1.0",
"esm-env": "^1.2.2", "esm-env": "^1.2.1",
"import-meta-resolve": "^4.1.0", "import-meta-resolve": "^4.1.0",
"kleur": "^4.1.5", "kleur": "^4.1.5",
"magic-string": "^0.30.5", "magic-string": "^0.30.5",
"mrmime": "^2.0.0", "mrmime": "^2.0.0",
"sade": "^1.8.1", "sade": "^1.8.1",
"set-cookie-parser": "^2.6.0", "set-cookie-parser": "^2.6.0",
"sirv": "^3.0.0" "sirv": "^3.0.0",
"tiny-glob": "^0.2.9"
}, },
"bin": { "bin": {
"svelte-kit": "svelte-kit.js" "svelte-kit": "svelte-kit.js"
@ -1056,9 +1039,9 @@
} }
}, },
"node_modules/@sveltestrap/sveltestrap": { "node_modules/@sveltestrap/sveltestrap": {
"version": "7.1.0", "version": "6.2.7",
"resolved": "https://registry.npmjs.org/@sveltestrap/sveltestrap/-/sveltestrap-7.1.0.tgz", "resolved": "https://registry.npmjs.org/@sveltestrap/sveltestrap/-/sveltestrap-6.2.7.tgz",
"integrity": "sha512-TpIx25kqLV+z+VD3yfqYayOI1IaCeWFbT0uqM6NfA4vQgDs9PjFwmjkU4YEAlV/ngs9e7xPmaRWE7lkrg4Miow==", "integrity": "sha512-WwLLfAFUb42BGuRrf3Vbct30bQMzlEMMipN/MfxhjuLTmLQeW9muVJfPyvjtWS+mY+RjkSCoHvAp/ZobP1NLlQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@popperjs/core": "^2.11.8" "@popperjs/core": "^2.11.8"
@ -1109,6 +1092,15 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
} }
}, },
"node_modules/acorn-typescript": {
"version": "1.4.13",
"resolved": "https://registry.npmjs.org/acorn-typescript/-/acorn-typescript-1.4.13.tgz",
"integrity": "sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q==",
"license": "MIT",
"peerDependencies": {
"acorn": ">=8.9.0"
}
},
"node_modules/ajv": { "node_modules/ajv": {
"version": "6.12.6", "version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@ -1416,23 +1408,22 @@
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
"version": "9.23.0", "version": "9.18.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz",
"integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1", "@eslint-community/regexpp": "^4.12.1",
"@eslint/config-array": "^0.19.2", "@eslint/config-array": "^0.19.0",
"@eslint/config-helpers": "^0.2.0", "@eslint/core": "^0.10.0",
"@eslint/core": "^0.12.0", "@eslint/eslintrc": "^3.2.0",
"@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.18.0",
"@eslint/js": "9.23.0", "@eslint/plugin-kit": "^0.2.5",
"@eslint/plugin-kit": "^0.2.7",
"@humanfs/node": "^0.16.6", "@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.2", "@humanwhocodes/retry": "^0.4.1",
"@types/estree": "^1.0.6", "@types/estree": "^1.0.6",
"@types/json-schema": "^7.0.15", "@types/json-schema": "^7.0.15",
"ajv": "^6.12.4", "ajv": "^6.12.4",
@ -1440,7 +1431,7 @@
"cross-spawn": "^7.0.6", "cross-spawn": "^7.0.6",
"debug": "^4.3.2", "debug": "^4.3.2",
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
"eslint-scope": "^8.3.0", "eslint-scope": "^8.2.0",
"eslint-visitor-keys": "^4.2.0", "eslint-visitor-keys": "^4.2.0",
"espree": "^10.3.0", "espree": "^10.3.0",
"esquery": "^1.5.0", "esquery": "^1.5.0",
@ -1477,9 +1468,9 @@
} }
}, },
"node_modules/eslint-compat-utils": { "node_modules/eslint-compat-utils": {
"version": "0.6.4", "version": "0.5.1",
"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.4.tgz", "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz",
"integrity": "sha512-/u+GQt8NMfXO8w17QendT4gvO5acfxQsAKirAt0LVxDnr2N8YLCVbregaNc/Yhp7NM128DwCaRvr8PLDfeNkQw==", "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1493,9 +1484,9 @@
} }
}, },
"node_modules/eslint-config-prettier": { "node_modules/eslint-config-prettier": {
"version": "10.1.1", "version": "9.1.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.1.tgz", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
"integrity": "sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==", "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"bin": { "bin": {
@ -1506,31 +1497,32 @@
} }
}, },
"node_modules/eslint-plugin-svelte": { "node_modules/eslint-plugin-svelte": {
"version": "3.3.3", "version": "2.46.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-3.3.3.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.46.1.tgz",
"integrity": "sha512-imzGqIgWbfsb/CR14d3k3M8MiVNGet+l9mjPhvo1Rm0Nxi0rNn4/eELqyR8FWlgKBMlGkOp2kshRJm0xpxNfHQ==", "integrity": "sha512-7xYr2o4NID/f9OEYMqxsEQsCsj4KaMy4q5sANaKkAb6/QeCjYFxRmDm2S3YC3A3pl1kyPZ/syOx/i7LcWYSbIw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.4.1", "@eslint-community/eslint-utils": "^4.4.0",
"@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/sourcemap-codec": "^1.4.15",
"eslint-compat-utils": "^0.6.4", "eslint-compat-utils": "^0.5.1",
"esutils": "^2.0.3", "esutils": "^2.0.3",
"known-css-properties": "^0.35.0", "known-css-properties": "^0.35.0",
"postcss": "^8.4.49", "postcss": "^8.4.38",
"postcss-load-config": "^3.1.4", "postcss-load-config": "^3.1.4",
"postcss-safe-parser": "^7.0.0", "postcss-safe-parser": "^6.0.0",
"semver": "^7.6.3", "postcss-selector-parser": "^6.1.0",
"svelte-eslint-parser": "^1.0.1" "semver": "^7.6.2",
"svelte-eslint-parser": "^0.43.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^14.17.0 || >=16.0.0"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/ota-meshi" "url": "https://github.com/sponsors/ota-meshi"
}, },
"peerDependencies": { "peerDependencies": {
"eslint": "^8.57.1 || ^9.0.0", "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0",
"svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
@ -1540,9 +1532,9 @@
} }
}, },
"node_modules/eslint-scope": { "node_modules/eslint-scope": {
"version": "8.3.0", "version": "8.2.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
"integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==",
"dev": true, "dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
@ -1607,9 +1599,9 @@
} }
}, },
"node_modules/esrap": { "node_modules/esrap": {
"version": "1.4.5", "version": "1.4.3",
"resolved": "https://registry.npmjs.org/esrap/-/esrap-1.4.5.tgz", "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.4.3.tgz",
"integrity": "sha512-CjNMjkBWWZeHn+VX+gS8YvFwJ5+NDhg8aWZBSFJPR8qQduDNjbJodA2WcwCm7uQa5Rjqj+nZvVmceg1RbHFB9g==", "integrity": "sha512-Xddc1RsoFJ4z9nR7W7BFaEPIp4UXoeQ0+077UdWLxbafMQFyU79sQJMk7kxNgRwQ9/aVgaKacCHC2pUACGwmYw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15" "@jridgewell/sourcemap-codec": "^1.4.15"
@ -1761,6 +1753,20 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/globalyzer": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz",
"integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==",
"dev": true,
"license": "MIT"
},
"node_modules/globrex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
"dev": true,
"license": "MIT"
},
"node_modules/has-flag": { "node_modules/has-flag": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@ -2138,9 +2144,9 @@
"license": "ISC" "license": "ISC"
}, },
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.5.1", "version": "8.4.49",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
"integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -2158,7 +2164,7 @@
], ],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"nanoid": "^3.3.8", "nanoid": "^3.3.7",
"picocolors": "^1.1.1", "picocolors": "^1.1.1",
"source-map-js": "^1.2.1" "source-map-js": "^1.2.1"
}, },
@ -2197,30 +2203,20 @@
} }
}, },
"node_modules/postcss-safe-parser": { "node_modules/postcss-safe-parser": {
"version": "7.0.1", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
"integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
"dev": true, "dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss-safe-parser"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=18.0" "node": ">=12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
}, },
"peerDependencies": { "peerDependencies": {
"postcss": "^8.4.31" "postcss": "^8.3.3"
} }
}, },
"node_modules/postcss-scss": { "node_modules/postcss-scss": {
@ -2251,9 +2247,9 @@
} }
}, },
"node_modules/postcss-selector-parser": { "node_modules/postcss-selector-parser": {
"version": "7.1.0", "version": "6.1.2",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
"integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -2275,9 +2271,9 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "3.5.3", "version": "3.4.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"bin": { "bin": {
@ -2322,9 +2318,9 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.32.0", "version": "4.30.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.32.0.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz",
"integrity": "sha512-JmrhfQR31Q4AuNBjjAX4s+a/Pu/Q8Q9iwjWBsjRH1q52SPFE2NqRMK6fUZKKnvKO6id+h7JIRf0oYsph53eATg==", "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -2338,25 +2334,25 @@
"npm": ">=8.0.0" "npm": ">=8.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.32.0", "@rollup/rollup-android-arm-eabi": "4.30.1",
"@rollup/rollup-android-arm64": "4.32.0", "@rollup/rollup-android-arm64": "4.30.1",
"@rollup/rollup-darwin-arm64": "4.32.0", "@rollup/rollup-darwin-arm64": "4.30.1",
"@rollup/rollup-darwin-x64": "4.32.0", "@rollup/rollup-darwin-x64": "4.30.1",
"@rollup/rollup-freebsd-arm64": "4.32.0", "@rollup/rollup-freebsd-arm64": "4.30.1",
"@rollup/rollup-freebsd-x64": "4.32.0", "@rollup/rollup-freebsd-x64": "4.30.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.32.0", "@rollup/rollup-linux-arm-gnueabihf": "4.30.1",
"@rollup/rollup-linux-arm-musleabihf": "4.32.0", "@rollup/rollup-linux-arm-musleabihf": "4.30.1",
"@rollup/rollup-linux-arm64-gnu": "4.32.0", "@rollup/rollup-linux-arm64-gnu": "4.30.1",
"@rollup/rollup-linux-arm64-musl": "4.32.0", "@rollup/rollup-linux-arm64-musl": "4.30.1",
"@rollup/rollup-linux-loongarch64-gnu": "4.32.0", "@rollup/rollup-linux-loongarch64-gnu": "4.30.1",
"@rollup/rollup-linux-powerpc64le-gnu": "4.32.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1",
"@rollup/rollup-linux-riscv64-gnu": "4.32.0", "@rollup/rollup-linux-riscv64-gnu": "4.30.1",
"@rollup/rollup-linux-s390x-gnu": "4.32.0", "@rollup/rollup-linux-s390x-gnu": "4.30.1",
"@rollup/rollup-linux-x64-gnu": "4.32.0", "@rollup/rollup-linux-x64-gnu": "4.30.1",
"@rollup/rollup-linux-x64-musl": "4.32.0", "@rollup/rollup-linux-x64-musl": "4.30.1",
"@rollup/rollup-win32-arm64-msvc": "4.32.0", "@rollup/rollup-win32-arm64-msvc": "4.30.1",
"@rollup/rollup-win32-ia32-msvc": "4.32.0", "@rollup/rollup-win32-ia32-msvc": "4.30.1",
"@rollup/rollup-win32-x64-msvc": "4.32.0", "@rollup/rollup-win32-x64-msvc": "4.30.1",
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },
@ -2468,16 +2464,16 @@
} }
}, },
"node_modules/svelte": { "node_modules/svelte": {
"version": "5.25.3", "version": "5.19.0",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.25.3.tgz", "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.19.0.tgz",
"integrity": "sha512-J9rcZ/xVJonAoESqVGHHZhrNdVbrCfkdB41BP6eiwHMoFShD9it3yZXApVYMHdGfCshBsZCKsajwJeBbS/M1zg==", "integrity": "sha512-qvd2GvvYnJxS/MteQKFSMyq8cQrAAut28QZ39ySv9k3ggmhw4Au4Rfcsqva74i0xMys//OhbhVCNfXPrDzL/Bg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@ampproject/remapping": "^2.3.0", "@ampproject/remapping": "^2.3.0",
"@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/sourcemap-codec": "^1.5.0",
"@sveltejs/acorn-typescript": "^1.0.5",
"@types/estree": "^1.0.5", "@types/estree": "^1.0.5",
"acorn": "^8.12.1", "acorn": "^8.12.1",
"acorn-typescript": "^1.4.13",
"aria-query": "^5.3.1", "aria-query": "^5.3.1",
"axobject-query": "^4.1.0", "axobject-query": "^4.1.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
@ -2493,21 +2489,20 @@
} }
}, },
"node_modules/svelte-eslint-parser": { "node_modules/svelte-eslint-parser": {
"version": "1.1.1", "version": "0.43.0",
"resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-1.1.1.tgz", "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.43.0.tgz",
"integrity": "sha512-QLVGPIMDettl30qRHXU2VrPvVJKG8GsGstye7n8rFbEiu3gEARksuQg9Xu4GzubNxhGNM8stfBZkhyMbBQmjFA==", "integrity": "sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"eslint-scope": "^8.2.0", "eslint-scope": "^7.2.2",
"eslint-visitor-keys": "^4.0.0", "eslint-visitor-keys": "^3.4.3",
"espree": "^10.0.0", "espree": "^9.6.1",
"postcss": "^8.4.49", "postcss": "^8.4.39",
"postcss-scss": "^4.0.9", "postcss-scss": "^4.0.9"
"postcss-selector-parser": "^7.0.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/ota-meshi" "url": "https://github.com/sponsors/ota-meshi"
@ -2521,6 +2516,54 @@
} }
} }
}, },
"node_modules/svelte-eslint-parser/node_modules/eslint-scope": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
"integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^5.2.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/svelte-eslint-parser/node_modules/eslint-visitor-keys": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/svelte-eslint-parser/node_modules/espree": {
"version": "9.6.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"acorn": "^8.9.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/svelte-hmr": { "node_modules/svelte-hmr": {
"version": "0.16.0", "version": "0.16.0",
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz",
@ -2534,6 +2577,17 @@
"svelte": "^3.19.0 || ^4.0.0" "svelte": "^3.19.0 || ^4.0.0"
} }
}, },
"node_modules/tiny-glob": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz",
"integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==",
"dev": true,
"license": "MIT",
"dependencies": {
"globalyzer": "0.1.0",
"globrex": "^0.1.2"
}
},
"node_modules/totalist": { "node_modules/totalist": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
@ -2575,9 +2629,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "5.4.15", "version": "5.4.11",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.15.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz",
"integrity": "sha512-6ANcZRivqL/4WtwPGTKNaosuNJr5tWiftOC7liM7G9+rMb8+oeJeyzymDu4rTN93seySBmbjSfsS3Vzr19KNtA==", "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View file

@ -14,8 +14,8 @@
"@sveltejs/kit": "^2.0.0", "@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0",
"eslint": "^9.0.0", "eslint": "^9.0.0",
"eslint-config-prettier": "^10.0.0", "eslint-config-prettier": "^9.0.0",
"eslint-plugin-svelte": "^3.0.0", "eslint-plugin-svelte": "^2.35.1",
"prettier": "^3.0.0", "prettier": "^3.0.0",
"prettier-plugin-svelte": "^3.1.2", "prettier-plugin-svelte": "^3.1.2",
"svelte": "^5.0.0", "svelte": "^5.0.0",
@ -25,6 +25,6 @@
"dependencies": { "dependencies": {
"bootstrap": "^5.2.2", "bootstrap": "^5.2.2",
"bootstrap-icons": "^1.9.1", "bootstrap-icons": "^1.9.1",
"@sveltestrap/sveltestrap": "^7.0.0" "@sveltestrap/sveltestrap": "^6.2.1"
} }
} }

View file

@ -9,14 +9,12 @@ import (
"log" "log"
"net/http" "net/http"
"strconv" "strconv"
"srs.epita.fr/fic-server/libfic"
) )
type AirbusAPI struct { type AirbusAPI struct {
BaseURL string BaseURL string
Token string Token string
SessionUUID string SessionID int64
InsecureSkipVerify bool InsecureSkipVerify bool
} }
@ -53,7 +51,7 @@ func (a *AirbusAPI) request(method, endpoint string, data io.Reader, out interfa
if out != nil { if out != nil {
jdec := json.NewDecoder(resp.Body) jdec := json.NewDecoder(resp.Body)
if err := jdec.Decode(&fic.CyberrangeAPIResponse{Data: out}); err != nil { if err := jdec.Decode(out); err != nil {
return fmt.Errorf("an error occurs when trying to decode response: %w", err) return fmt.Errorf("an error occurs when trying to decode response: %w", err)
} }
} }
@ -89,7 +87,7 @@ type AirbusUser struct {
} }
func (a *AirbusAPI) GetUsers() (users AirbusUserData, err error) { func (a *AirbusAPI) GetUsers() (users AirbusUserData, err error) {
err = a.request("GET", fmt.Sprintf("/sessions/%s/users", a.SessionUUID), nil, &users) err = a.request("GET", fmt.Sprintf("/sessions/%d/users", a.SessionID), nil, &users)
return return
} }
@ -139,7 +137,7 @@ type AirbusChallenge struct {
} }
func (a *AirbusAPI) GetChallenges() (challenges AirbusChallengeData, err error) { func (a *AirbusAPI) GetChallenges() (challenges AirbusChallengeData, err error) {
err = a.request("GET", fmt.Sprintf("/v1/sessions/%s/challenges", a.SessionUUID), nil, &challenges) err = a.request("GET", fmt.Sprintf("/v1/sessions/%d/challenges", a.SessionID), nil, &challenges)
return return
} }
@ -158,23 +156,25 @@ func (a *AirbusAPI) GetChallengeFromName(name string) (*AirbusChallenge, error)
return nil, fmt.Errorf("unable to find challenge %q", name) return nil, fmt.Errorf("unable to find challenge %q", name)
} }
func (a *AirbusAPI) ValidateChallengeFromUser(team *fic.CyberrangeTeam, challengeId AirbusChallengeId) (err error) { func (a *AirbusAPI) ValidateChallengeFromUser(team *AirbusTeam, challengeId AirbusChallengeId) (err error) {
log.Printf("ValidateChallenge: %s, %s, %s", a.SessionUUID, challengeId.String(), team.Members[0].UUID) log.Printf("ValidateChallenge: %d, %s, %d", a.SessionID, challengeId.String(), team.Members[0].ID)
if dryRun { if dryRun {
return return
} }
err = a.request("GET", fmt.Sprintf("/v1/sessions/%s/%s/%s/validate", a.SessionUUID, challengeId.String(), team.Members[0].UUID), nil, nil) err = a.request("GET", fmt.Sprintf("/v1/sessions/%d/%s/%d/validate", a.SessionID, challengeId.String(), team.Members[0].ID), nil, nil)
return return
} }
type AirbusUserAwards struct { type AirbusUserAwards struct {
UserId int64 `json:"gaming_user_id"`
Message string `json:"name"` Message string `json:"name"`
Value int64 `json:"value"` Value int64 `json:"value"`
} }
func (a *AirbusAPI) AwardUser(team *fic.CyberrangeTeam, value int64, message string) (err error) { func (a *AirbusAPI) AwardUser(team *AirbusTeam, value int64, message string) (err error) {
awards := AirbusUserAwards{ awards := AirbusUserAwards{
UserId: team.Members[0].ID,
Message: message, Message: message,
Value: value, Value: value,
} }
@ -190,7 +190,7 @@ func (a *AirbusAPI) AwardUser(team *fic.CyberrangeTeam, value int64, message str
return return
} }
err = a.request("POST", fmt.Sprintf("/v1/sessions/%s/%s/awards", a.SessionUUID, team.Members[0].UUID), bytes.NewReader(marshalled), nil) err = a.request("POST", fmt.Sprintf("/v1/sessions/%d/awards", a.SessionID), bytes.NewReader(marshalled), nil)
if err != nil { if err != nil {
return err return err
} }

View file

@ -16,8 +16,6 @@ import (
"time" "time"
"gopkg.in/fsnotify.v1" "gopkg.in/fsnotify.v1"
"srs.epita.fr/fic-server/libfic"
) )
var ( var (
@ -79,8 +77,12 @@ func main() {
fd.Close() fd.Close()
} }
if v, exists := os.LookupEnv("AIRBUS_SESSION_UUID"); exists { if v, exists := os.LookupEnv("AIRBUS_SESSIONID"); exists {
api.SessionUUID = v var err error
api.SessionID, err = strconv.ParseInt(v, 10, 64)
if err != nil {
log.Fatal("AIRBUS_SESSIONID is invalid: ", err.Error())
}
} else if v, exists := os.LookupEnv("AIRBUS_SESSION_NAME_FILE"); exists { } else if v, exists := os.LookupEnv("AIRBUS_SESSION_NAME_FILE"); exists {
fd, err := os.Open(v) fd, err := os.Open(v)
if err != nil { if err != nil {
@ -99,15 +101,15 @@ func main() {
for _, session := range sessions { for _, session := range sessions {
if session.Name == v { if session.Name == v {
api.SessionUUID = session.UUID api.SessionID = session.ID
break break
} }
} }
if api.SessionUUID == "" { if api.SessionID == 0 {
log.Fatal("Session ID not found") log.Fatal("Session ID not found")
} else { } else {
log.Println("Session ID discovered: ", api.SessionUUID) log.Println("Session ID discovered: ", api.SessionID)
} }
} else if v, exists := os.LookupEnv("AIRBUS_SESSION_NAME"); exists { } else if v, exists := os.LookupEnv("AIRBUS_SESSION_NAME"); exists {
sessions, err := api.GetSessions() sessions, err := api.GetSessions()
@ -115,19 +117,17 @@ func main() {
log.Fatal("Unable to retrieve session: ", err) log.Fatal("Unable to retrieve session: ", err)
} }
found := false
for _, session := range sessions { for _, session := range sessions {
if session.Name == v { if session.Name == v {
api.SessionUUID = session.UUID api.SessionID = session.ID
found = true
break break
} }
} }
if !found { if api.SessionID == 0 {
log.Fatal("Session ID not found") log.Fatal("Session ID not found")
} else { } else {
log.Println("Session ID discovered: ", api.SessionUUID) log.Println("Session ID discovered: ", api.SessionID)
} }
} else { } else {
sessions, err := api.GetSessions() sessions, err := api.GetSessions()
@ -138,7 +138,7 @@ func main() {
log.Println("Please define your AIRBUS_SESSIONID or AIRBUS_SESSION_NAME.") log.Println("Please define your AIRBUS_SESSIONID or AIRBUS_SESSION_NAME.")
log.Println("Existing sessions are:") log.Println("Existing sessions are:")
for _, session := range sessions { for _, session := range sessions {
log.Printf(" - %s: %q", session.UUID, session.Name) log.Printf(" - %d: %q", session.ID, session.Name)
} }
os.Exit(1) os.Exit(1)
} }
@ -156,11 +156,11 @@ func main() {
} }
fmt.Println("## Airbus' registered teams:") fmt.Println("## Airbus' registered teams:")
fmt.Println("----------------------------------------------------------------------------------") fmt.Println("-------------------------------------------")
fmt.Println(" UUID | Name | Nb. | Score | Rank") fmt.Println(" ID | Name | Nb. | Score | Rank")
fmt.Println("----------------------------------------------------------------------------------") fmt.Println("-------------------------------------------")
for _, team := range teams { for _, team := range teams {
fmt.Printf(" %s | % 20s | % 3d | % 5d | % 3d\n", team.UUID, team.Name, len(team.Members), team.Score, team.Rank) fmt.Printf("% 2d | % 15s | % 3d | % 5d | % 3d\n", team.ID, team.Name, len(team.Members), team.Score, team.Rank)
} }
case "rank": case "rank":
teams, err := api.GetTeams() teams, err := api.GetTeams()
@ -169,7 +169,7 @@ func main() {
os.Exit(1) os.Exit(1)
} }
ranking := []*fic.CyberrangeTeam{} ranking := []*AirbusTeam{}
for _, team := range teams { for _, team := range teams {
tmp := team tmp := team
ranking = append(ranking, &tmp) ranking = append(ranking, &tmp)
@ -178,11 +178,11 @@ func main() {
sort.Sort(sort.Reverse(ByScore(ranking))) sort.Sort(sort.Reverse(ByScore(ranking)))
fmt.Println("## Airbus' ranking:") fmt.Println("## Airbus' ranking:")
fmt.Println("----------------------------------------------------------------------------") fmt.Println("-------------------------------------")
fmt.Println(" Rank | Name | UUID | Score") fmt.Println(" Rank | Name | ID | Score")
fmt.Println("----------------------------------------------------------------------------") fmt.Println("-------------------------------------")
for _, team := range ranking { for _, team := range ranking {
fmt.Printf("% 5d | % 20s | %s | % 5d\n", team.Rank, team.Name, team.UUID, team.Score) fmt.Printf("% 5d | % 15s |% 3d | % 5d\n", team.Rank, team.Name, team.ID, team.Score)
} }
case "get": case "get":
teams, err := api.GetTeams() teams, err := api.GetTeams()
@ -191,18 +191,22 @@ func main() {
os.Exit(1) os.Exit(1)
} }
teamid := args[1] teamid, err := strconv.ParseInt(args[1], 10, 64)
if err != nil {
log.Println(err)
os.Exit(1)
}
for _, team := range teams { for _, team := range teams {
if team.UUID == teamid { if team.ID == teamid {
fmt.Printf("## Airbus' registered team %s:\n\nUUID: %s\nName: %s\nScore: %d\nRank: %d\nMembers:\n", teamid, team.UUID, team.Name, team.Score, team.Rank) fmt.Printf("## Airbus' registered team %d:\n\nID: %d\nName: %s\nScore: %d\nRank: %d\nMembers:\n", teamid, team.ID, team.Name, team.Score, team.Rank)
for _, member := range team.Members { for _, member := range team.Members {
fmt.Printf(" - UUID: %s\n Name: %s\n Nickname: %s\n E-mail: %s\n", member.UUID, member.Name, member.Nickname, member.EMail) fmt.Printf(" - ID: %d\n Name: %s\n Nickname: %s\n E-mail: %s\n", member.ID, member.Name, member.Nickname, member.EMail)
} }
os.Exit(0) os.Exit(0)
} }
} }
fmt.Printf("Team %s not found. Use 'list' to view all existing teams\n", teamid) fmt.Printf("Team %d not found. Use 'list' to view all existing teams\n", teamid)
case "award": case "award":
if len(args) < 3 { if len(args) < 3 {
fmt.Println("award <TEAM_ID> <VALUE> <MESSAGE>") fmt.Println("award <TEAM_ID> <VALUE> <MESSAGE>")
@ -215,7 +219,11 @@ func main() {
os.Exit(1) os.Exit(1)
} }
teamid := args[1] teamid, err := strconv.ParseInt(args[1], 10, 64)
if err != nil {
log.Println("Invalid team id", err)
os.Exit(1)
}
value, err := strconv.ParseInt(args[2], 10, 64) value, err := strconv.ParseInt(args[2], 10, 64)
if err != nil { if err != nil {
@ -224,7 +232,7 @@ func main() {
} }
for _, team := range teams { for _, team := range teams {
if team.UUID == teamid { if team.ID == teamid {
err = api.AwardUser(&team, value, strings.Join(args[3:], " ")) err = api.AwardUser(&team, value, strings.Join(args[3:], " "))
if err != nil { if err != nil {
log.Println("Unable to award team:", err) log.Println("Unable to award team:", err)
@ -235,7 +243,7 @@ func main() {
os.Exit(0) os.Exit(0)
} }
} }
fmt.Printf("Team %s not found. Use 'list' to view all existing teams\n", teamid) fmt.Printf("Team %d not found. Use 'list' to view all existing teams\n", teamid)
} }
os.Exit(0) os.Exit(0)

View file

@ -1,18 +1,12 @@
package main package main
import ( import ()
"time"
)
type Session struct { type Session struct {
Name string `json:"name"` Name string `json:"name"`
QuestionValidation string `json:"question_validation"` Status string `json:"status"`
Status string `json:"status"` ID int64 `json:"id"`
UUID string `json:"uuid"` Mode string `json:"mode"`
Mode string `json:"mode"`
Difficulty int `json:"difficulty"`
StartedAt time.Time `json:"start_at"`
FinishAt time.Time `json:"finish_at"`
} }
func (a *AirbusAPI) GetSessions() (ret []Session, err error) { func (a *AirbusAPI) GetSessions() (ret []Session, err error) {

View file

@ -2,27 +2,44 @@ package main
import ( import (
"fmt" "fmt"
"srs.epita.fr/fic-server/libfic"
) )
func (a *AirbusAPI) GetTeams() ([]fic.CyberrangeTeam, error) { type AirbusTeam struct {
var data []fic.CyberrangeTeam ID int64 `json:"id"`
err := a.request("GET", fmt.Sprintf("/v1/sessions/%s/teams", a.SessionUUID), nil, &data) Members []TeamMember `json:"members"`
Name string `json:"name"`
Score int64 `json:"score"`
Rank int `json:"rank"`
}
type TeamMember struct {
ID int64 `json:"id"`
Name string `json:"name"`
Nickname string `json:"nickname"`
EMail string `json:"email"`
}
type airbusDataTeam struct {
Data []AirbusTeam `json:"data"`
}
func (a *AirbusAPI) GetTeams() ([]AirbusTeam, error) {
var data airbusDataTeam
err := a.request("GET", fmt.Sprintf("/v1/sessions/%d/teams", a.SessionID), nil, &data)
if err != nil { if err != nil {
return nil, err return nil, err
} else { } else {
return data, nil return data.Data, nil
} }
} }
type ByRank []*fic.CyberrangeTeam type ByRank []*AirbusTeam
func (a ByRank) Len() int { return len(a) } func (a ByRank) Len() int { return len(a) }
func (a ByRank) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByRank) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByRank) Less(i, j int) bool { return a[i].Rank < a[j].Rank } func (a ByRank) Less(i, j int) bool { return a[i].Rank < a[j].Rank }
type ByScore []*fic.CyberrangeTeam type ByScore []*AirbusTeam
func (a ByScore) Len() int { return len(a) } func (a ByScore) Len() int { return len(a) }
func (a ByScore) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByScore) Swap(i, j int) { a[i], a[j] = a[j], a[i] }

View file

@ -0,0 +1,102 @@
[
{
"name": "#D\u00e9fendonsEnsemble",
"score": 0
},
{
"name": "Les Pires Hat",
"score": 0
},
{
"name": "Esnarcotrafiquants",
"score": 0
},
{
"name": "Quarkslab",
"score": 0
},
{
"name": "HackademINT",
"score": 0
},
{
"name": "Phreaks 2600",
"score": 0
},
{
"name": "Rhackgondins",
"score": 0
},
{
"name": "Team France",
"score": 0
},
{
"name": "Hack UTT",
"score": 0
},
{
"name": "HDRF",
"score": 0
},
{
"name": "#199",
"score": 0
},
{
"name": "Hackday",
"score": 0
},
{
"name": "GCC",
"score": 0
},
{
"name": "Apeltek",
"score": 0
},
{
"name": "Hackvengers",
"score": 0
},
{
"name": "Guardia Cyber Squad",
"score": 0
},
{
"name": "F0r3nS0C",
"score": 0
},
{
"name": "Oteriack",
"score": 0
},
{
"name": "Cervelles de Canuts",
"score": 0
},
{
"name": "Next'H4ck",
"score": 0
},
{
"name": "Overflowl",
"score": 0
},
{
"name": "Capgemini Aces of Spades",
"score": 0
},
{
"name": "DLS",
"score": 0
},
{
"name": "ESGI",
"score": 0
},
{
"name": "0xECE",
"score": 0
}
]

View file

@ -5,8 +5,6 @@ import (
"log" "log"
"os" "os"
"time" "time"
"srs.epita.fr/fic-server/libfic"
) )
type TSValue struct { type TSValue struct {
@ -34,7 +32,7 @@ func loadTS(tspath string) (timestamp map[string]*TSValue, err error) {
} }
} }
func loadTSFromAPI(teams map[string]*fic.CyberrangeTeam) (timestamp map[string]*TSValue, err error) { func loadTSFromAPI(teams map[string]*AirbusTeam) (timestamp map[string]*TSValue, err error) {
now := time.Now() now := time.Now()
timestamp = map[string]*TSValue{} timestamp = map[string]*TSValue{}

View file

@ -23,7 +23,7 @@ type Walker struct {
Exercices AirbusExercicesBindings Exercices AirbusExercicesBindings
Teams map[string]fic.ExportedTeam Teams map[string]fic.ExportedTeam
RevTeams map[string]string RevTeams map[string]string
TeamBindings map[string]*fic.CyberrangeTeam TeamBindings map[string]*AirbusTeam
API AirbusAPI API AirbusAPI
Coeff float64 Coeff float64
} }
@ -35,11 +35,11 @@ func (w *Walker) fetchTeams() error {
} }
w.RevTeams = map[string]string{} w.RevTeams = map[string]string{}
w.TeamBindings = map[string]*fic.CyberrangeTeam{} w.TeamBindings = map[string]*AirbusTeam{}
for tid, team := range w.Teams { for tid, team := range w.Teams {
for i, t := range teams { for i, t := range teams {
if team.Name == t.Name || team.ExternalId == t.Name || team.ExternalId == t.UUID { if team.Name == t.Name || team.ExternalId == t.Name {
w.TeamBindings[tid] = &teams[i] w.TeamBindings[tid] = &teams[i]
break break
} }
@ -143,7 +143,7 @@ func (w *Walker) WalkScore(path string, d os.DirEntry, err error) error {
return nil return nil
} }
func (w *Walker) TreatScoreGrid(path string, airbusTeam *fic.CyberrangeTeam) error { func (w *Walker) TreatScoreGrid(path string, airbusTeam *AirbusTeam) error {
// Read score grid // Read score grid
fdscores, err := os.Open(path) fdscores, err := os.Open(path)
if err != nil { if err != nil {