Date: Mon, 8 Jun 2026 15:58:49 +0200
Subject: [PATCH 21/40] =?UTF-8?q?sammanfattat=20gjorda=20=C3=A4ndringar=20?=
=?UTF-8?q?i=20filen=20fas2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 37 +------------
backend/middleware/rateLimiter.js | 2 +-
backend/server.js | 29 +++++-----
fas2.md | 64 +++++++++++++++++++++++
frontend/src/App.jsx | 6 +--
frontend/src/api.js | 5 +-
frontend/src/components/PostMessage.jsx | 4 +-
frontend/src/components/SingleMessage.jsx | 6 +--
8 files changed, 91 insertions(+), 62 deletions(-)
create mode 100644 fas2.md
diff --git a/README.md b/README.md
index 2d5b3155..3d6c1714 100644
--- a/README.md
+++ b/README.md
@@ -1,37 +1,2 @@
# yh-message-app-fullstack
-
-Säkerhetskrav som jag inte ändrat i koden:
-
-2. En användare ska inte kunna ändra sina behörigheter till admin
-
-Applikationen har ingen admin-roll implementerad, vilket innebär att det inte finns någon möjlighet för en användare att eskalera sina behörigheter till admin. User-modellen innehåller inget role-fält och det finns inga endpoints som tillåter en användare att ändra sina egna behörigheter. Alla användare har samma behörighetsnivå och kan endast påverka sina egna meddelanden.
-
-Att det inte finns några endpoints där användare kan ändra sina behörigheter betyder att det inte finns någon route i server.js, till exempel PATCH /users/:id, där en användare kan skicka in data för att uppdatera sitt eget konto — som till exempel { role: "admin" }. Eftersom den routen inte existerar finns det inget API-anrop att göra för att försöka ge sig själv högre behörigheter.
-
-Om vi i framtiden vill implementera en adminroll skulle det vara viktigt att: v
-role aldrig sätts via API:et: en användare ska inte kunna skicka { role: "admin" } vid registrering eller via en PATCH-route och få det sparat
-role ska sättas direkt i databasen: en administratör med databasåtkomst sätter rollen manuellt
-requireAdmin-middleware: en kontroll som körs innan admin-routes och avvisar alla som inte har rätt roll
-authenticateUser körs alltid före requireAdmin: annars kan man nå admin-routes utan att vara inloggad alls
-
-7. För att återställa lösenord krävs en engångskod skickad till användarens e-post.
-
-För att implementera lösenordsåterställning via engångskod behövs flera delar. Först behövs en e-posttjänst, till exempel Nodemailer, som kan skicka ett e-postmeddelande med en engångskod till användaren.
-
-Implementationen skulle börja med en POST /forgot-password-route som tar emot användarens e-postadress, genererar en tidsbegränsad engångskod och skickar den till användaren via e-post med exempelvis Nodemailer.
-
-I databasen behöver User-modellen utökas med ett fält för engångskoden och ett fält för när koden går ut, så att koden inte kan återanvändas eller användas efter att tidsgränsen passerat.
-
-Därefter behövs en POST /reset-password-route där användaren anger koden tillsammans med sitt nya lösenord. Backenden validerar att koden stämmer och inte har gått ut, varefter det nya lösenordet hashas med bcrypt och sparas i databasen, på samma sätt som vid registrering.
-
-
-8. All kommunikation ska vara krypterad via HTTPS och TLS.
-Att kommunikation ska vara krypterad via HTTPS och TLS fixas i Render när man deployar där. Render sätter automatiskt upp HTTPS och TLS för backenden. Det man kan göra är att se till att ens base_url i frontend pekar på en https://-adress och inte http://
-
-Om man inte deployar via render så måste man skaffa ett TLS-certifikat, och en reverse proxy som tar emot https-anrop, dekrypterar och vidarebefordrar anropen till min express-server.
-
-9. Systemet ska logga vem som skapade, redigerade och raderade varje meddelande.
-
-För att logga vem som skapade, redigerade och raderade meddelanden bör en separat AuditLog-collection i databasen implementeras. Varje gång ett meddelande skapas, redigeras eller raderas sparas en logg-post med action (created, edited, deleted), meddelande-id, användar-id och tidsstämpel.
-
-Loggarna nås direkt i databasen via MongoDB Compass eller MongoDB Atlas av den med databasåtkomst. I en produktionssatt app med admin-roll skulle loggarna istället nås via en skyddad endpoint som endast administratörer har tillgång till.
\ No newline at end of file
+Lagt till en fil med sammanfattning över de ändringar och förslag jag gjort för att uppfylla säkerhetskraven. Se filen fas2.md
\ No newline at end of file
diff --git a/backend/middleware/rateLimiter.js b/backend/middleware/rateLimiter.js
index 4ffacff4..6376d825 100644
--- a/backend/middleware/rateLimiter.js
+++ b/backend/middleware/rateLimiter.js
@@ -6,4 +6,4 @@ export const loginLimiter = rateLimit({
message: { success: false, message: "Too many login attempts, please try again after 15 minutes" }
})
-// här har jag lagt in en funktion LoginLimiter som använder express-rate-limit för att begränsa antalet inloggningsförsök till 5 per 15 minuter. Detta är en del av säkerhetskrav 6, som handlar om att implementera rate limiting för att skydda mot brute-force attacker. Sedan använder jag loginLimiter som middleware i app.post("/login") för att tillämpa denna begränsning på inloggningsförsöken.
\ No newline at end of file
+// Säkerhetskrav 6. Här har jag lagt in en funktion LoginLimiter som använder express-rate-limit för att begränsa antalet inloggningsförsök till 5 per 15 minuter. Sedan använder jag loginLimiter som middleware i server.js: app.post("/login") för att tillämpa denna begränsning på inloggningsförsöken.
\ No newline at end of file
diff --git a/backend/server.js b/backend/server.js
index 09594599..066e277c 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -11,8 +11,8 @@ import { authenticateUser } from "./middleware/auth.js"
import "./config/db.js"
import listEndpoints from "express-list-endpoints"
import { loginLimiter } from "./middleware/rateLimiter.js"
-// importerar middlewaren loginLimiter, vilket är en del av säkerhetskrav 6.
-import mongoSanitize from "express-mongo-sanitize" //importerar för att sanera input och skydda mot NoSQL-injection, vilket är en del av säkerhetskrav 1.
+// Säkerhetskrav 6: Importerar middlewaren loginLimiter
+import mongoSanitize from "express-mongo-sanitize" //Säkerhetskrav 1: Importerar för att sanera input och skydda mot NoSQL-injection.
if (!process.env.JWT_SECRET) throw new Error("JWT_SECRET is not set in .env")
@@ -25,7 +25,7 @@ app.use(cors({
}))
app.use(express.json())
-app.use(mongoSanitize()) // här används mongoSanitize för att sanera input och skydda mot NoSQL-injection. Säkerhetskrav 1.
+app.use(mongoSanitize()) //Säkerhetskrav 1. Här används mongoSanitize för att sanera input och skydda mot NoSQL-injection.
app.get("/", (req, res) => {
res.send(listEndpoints(app))
@@ -50,7 +50,7 @@ app.post("/register", async (req, res) => {
message: `A user with this ${field} already exists`
})
}
- // här hashas lösenord med bcrypt innan det sparas i databasen, vilket åtgärdar säkerhetskrav 5.
+ // Säkerhetskrav 5. Här hashas lösenord med bcrypt innan det sparas i databasen. Detta fanns med från början i koden.
// bcrypt är en envägsfunktion, lösenordet kan inte återskapas från hashen.
const hashedPassword = await bcrypt.hash(password, 10)
const user = new User({ username: username.trim(), email, password: hashedPassword })
@@ -80,7 +80,7 @@ app.post("/register", async (req, res) => {
}
})
-//lagt till middlewaren loginLimiter för att begränsa antalet inloggningsförsök, vilket är en del av säkerhetskrav 6.
+//Säkerhetskrav 6: Lagt till middlewaren loginLimiter för att begränsa antalet inloggningsförsök.
app.post("/login", loginLimiter, async (req, res) => {
try {
const { login, password } = req.body
@@ -96,7 +96,7 @@ app.post("/login", loginLimiter, async (req, res) => {
})
}
- // här jämförs det angivna lösenordet som hashas med det hashade lösenordet i databasen, vilket är en del av säkerhetsåtgärd 5.
+ // Säkerhetskrav 5: Här jämförs det angivna lösenordet som hashas med det hashade lösenordet i databasen. Detta fanns från början och jag har inte ändrat något.
const passwordMatch = await bcrypt.compare(password, user.password)
if (!passwordMatch) {
return res.status(401).json({
@@ -132,7 +132,7 @@ app.post("/login", loginLimiter, async (req, res) => {
const isValidId = (id) => mongoose.Types.ObjectId.isValid(id)
-//lagt till authenticateUser i app.get("/messages") så att endast inloggade användare kan se meddelanden. Det är en del av mitt säkerhetskrav 3, alltså att endast inloggade användare ska kunna se meddelanden.
+//Säkerhetskrav 3. Lagt till middlewaren authenticateUser så att endast inloggade användare kan se meddelanden.
app.get("/messages", authenticateUser, async (req, res) => {
try {
const messages = await Message.find()
@@ -145,11 +145,11 @@ app.get("/messages", authenticateUser, async (req, res) => {
res.status(500).json({ message: "Could not fetch messages" })
}
})
-//att authenicateUser finns med i app.post, gör att det krävs en giltig token för att skriva ett meddelande. Detta fanns redan med i koden från början. Uppfyller säkerhetskrav 3.
+//Säkerhetskrav 3. authenticateUser finns med i app.post, vilket gör att inloggning krävs för att posta ett meddelande. Detta fanns redan med i koden från början.
app.post("/messages", authenticateUser, async (req, res) => {
const text = req.body.message
if (!text || text.length < 3 || text.length > 140) {
- return res.status(400).json({ message: "Message must be between 3 and 140 characters" }) // detta är en del av säkerhetskrav 10, begränsing av längd på meddelanden.
+ return res.status(400).json({ message: "Message must be between 3 and 140 characters" }) // Säkerhetskrav 10. Ändrat begränsning av längd på meddelanden.
}
const message = new Message({ message: req.body.message, user: req.user._id })
try {
@@ -160,18 +160,18 @@ app.post("/messages", authenticateUser, async (req, res) => {
}
})
-//backend: Att authenicateUser finns med i app.patch(“/messages/:id gör att det krävs en giltig token för att redigera ett meddelande. Detta fanns redan med i koden från början.
+//Säkerhetskrav 3: Att authenicateUser finns med i app.patch(“/messages/:id gör att det krävs att man är inloggad för att redigera ett meddelande. Detta fanns med i koden från början.
app.patch("/messages/:id", authenticateUser, async (req, res) => {
if (!isValidId(req.params.id)) return res.status(400).json({ error: "Invalid message ID" })
try {
const message = await Message.findById(req.params.id)
if (!message) return res.status(404).json({ error: "Message not found" })
- //här under säkerställs att endast ägaren av meddelandet kan redigera det, annars kan vem som helst redigera alla meddelanden. detta var med i koden från början och uppfyller säkerhetskrav 4.
+ //Säkerhetskrav 4. Här under säkerställs att endast ägaren av meddelandet kan redigera det, genom att man jämför den inloggades id med id på meddelandet. Annars kan vem som helst redigera alla meddelanden. Detta var med i koden från början.
if (message.user.toString() !== req.user._id.toString()) {
return res.status(403).json({ error: "You can only edit your own messages" })
}
- // här lägger jag till en kontroll för att säkerställa att meddelandet är mellan 3 och 140 tecken, annars kan användare skicka in väldigt långa eller väldigt korta meddelanden. Detta är en del av säkerhetskrav 10.
+ //Säkerhetskrav 10: Här lägger jag till en kontroll för att säkerställa att meddelandet som redigeras är mellan 3 och 140 tecken.
const editedText = req.body.editedMessage
if (!editedText || editedText.length < 3 || editedText.length > 140) {
return res.status(400).json({ error: "Message must be between 3 and 140 characters" })
@@ -186,16 +186,15 @@ app.patch("/messages/:id", authenticateUser, async (req, res) => {
}
})
-// La till authenticateUser. Det löser delvis krav 4, alltså att ägarskap ska kontrolleras innan radering av meddelanden.
+// Säkerhetskrav 3/4: La till authenticateUser vid radering av meddelande, vilket gör att man måste vara inloggad för att ändra meddelande.
app.delete("/messages/:id", authenticateUser, async (req, res) => {
if (!isValidId(req.params.id)) return res.status(400).json({ error: "Invalid message ID" })
try {
const message = await Message.findById(req.params.id)
if (!message) return res.status(404).json({ error: "Message not found" })
- // här lägger jag till en kontroll för att säkerställa att endast ägaren av meddelandet kan radera det, annars kan vem som helst radera alla meddelanden. Säkerhetskrav 4.
+ // Säkerhetskrav 4. Här lägger jag till samma kontroll som finns vid redigering av meddelande för att säkerställa att endast ägaren av meddelandet kan radera det. Jämförelse av den inloggades id och meddelandets id.
if (message.user.toString() !== req.user._id.toString()) {
- console.log(`BLOCKED: User ${req.user._id} tried to delete message owned by ${message.user}`) //console.log för att testa så att det fungerar
return res.status(403).json({ error: "You can only delete your own messages" })
}
diff --git a/fas2.md b/fas2.md
new file mode 100644
index 00000000..7f1917d4
--- /dev/null
+++ b/fas2.md
@@ -0,0 +1,64 @@
+Kodändringar och förslag för att uppfylla säkerhetskraven.
+
+1. Krav: Backend ska validera och sanitera input, samt säkert hantera input från användare så att det inte kan tolkas som databaskommandon.
+
+Fixat genom att importera och använda mongoSanitize i server.js. Se filen för ändringarna.
+
+2. Krav: En användare ska inte kunna ändra sina behörigheter till admin
+
+Applikationen har ingen admin-roll implementerad, vilket innebär att det idag inte finns någon möjlighet för en användare att eskalera sina behörigheter till admin. User-modellen innehåller inget role-fält och det finns inga endpoints som tillåter en användare att ändra sina egna behörigheter. Alla användare har samma behörighetsnivå och kan endast påverka sina egna meddelanden.
+
+Att det inte finns några endpoints där användare kan ändra sina behörigheter betyder att det inte finns någon route i server.js, till exempel PATCH /users/:id, där en användare kan skicka in data för att uppdatera sitt eget konto — som till exempel { role: "admin" }. Eftersom den routen inte existerar finns det inget API-anrop att göra för att försöka ge sig själv högre behörigheter.
+
+Om vi i framtiden vill implementera en adminroll skulle det vara viktigt att:
+
+role aldrig sätts via API:et: en användare ska inte kunna skicka { role: "admin" } vid registrering eller via en PATCH-route och få det sparat
+
+role ska sättas direkt i databasen: en administratör med databasåtkomst sätter rollen manuellt
+
+requireAdmin-middleware: en kontroll som körs innan admin-routes och avvisar alla som inte har rätt roll
+
+authenticateUser körs alltid före requireAdmin: annars kan man nå admin-routes utan att vara inloggad alls
+
+3. Krav: Systemet ska kräva inloggning för att en användare ska kunna se, skriva eller redigera meddelanden.
+
+Uppfylldes till viss del redan, men har också gjort ändringar i backend och frontend för att uppfylla kravet. Se ändringar gjorda i server.js, app.jsx, samt postmessage.jsx och singlemessage.jsx.
+
+4. Krav: Innan redigering eller radering av ett meddelande ska systemet kontrollera att meddelandet är kopplat till den inloggade användaren.
+
+Uppfylldes till viss del redan vad gällde redigering av meddelande, men jag har gjort förändringar för radering av meddelanden. Se ändringar i server.js, singlemessage.jsx
+
+5. Krav: Lösenord ska aldrig lagras i klartext i databasen.
+
+Detta krav uppfylldes redan i koden. Se server.js för kommentarer.
+
+6. Krav: Systemet ska blockera inloggning efter 5 misslyckade försök.
+
+Detta la jag till genom rate-limiting. Se ny middleware i rateLimiter.js och användning av den i server.js
+
+7. Krav: För att återställa lösenord krävs en engångskod skickad till användarens e-post.
+
+För att implementera lösenordsåterställning via engångskod behövs flera delar. För det första behövs e funktion för att återställa lösenordet, samt en e-posttjänst, till exempel Nodemailer, som kan skicka ett e-postmeddelande med en engångskod till användaren.
+
+Implementationen skulle börja med en POST /forgot-password-route som tar emot användarens e-postadress, genererar en tidsbegränsad engångskod och skickar den till användaren via e-post med exempelvis Nodemailer.
+
+I databasen behöver User-modellen utökas med ett fält för engångskoden och ett fält för när koden går ut, så att koden inte kan återanvändas eller användas efter att tidsgränsen passerat.
+
+Därefter behövs en POST /reset-password-route där användaren anger koden tillsammans med sitt nya lösenord. Backenden validerar att koden stämmer och inte har gått ut, varefter det nya lösenordet hashas med bcrypt och sparas i databasen, på samma sätt som vid registrering.
+
+
+8. Krav: All kommunikation ska vara krypterad via HTTPS och TLS.
+
+För att anropen ska ske via HTTPS är det viktigt att BASE_URL i api.js pekar mot en https-adress. Just nu är URL:n i api.js en lokal host för utveckling, som går över http, men i produktion måste det vara en HTTPS-adress för att uppfylla säkerhetskravet-
+
+För att kommunikationen ska vara krypterad enligt TLS behöver vi skaffa ett TLS-certifikat, och en reverse-proxy som tar emot https-anrop, dekrypterar och vidarebefordrar anropen till min vår express-server.
+
+9. Systemet ska logga vem som skapade, redigerade och raderade varje meddelande.
+
+För att logga vem som skapade, redigerade och raderade meddelanden bör en separat AuditLog-collection i databasen implementeras. Varje gång ett meddelande skapas, redigeras eller raderas sparas en logg-post med action (created, edited, deleted), meddelande-id, användar-id och tidsstämpel.
+
+Loggarna nås direkt i databasen via MongoDB Compass eller MongoDB Atlas av den med databasåtkomst. I en produktionssatt app med admin-roll skulle loggarna istället nås via en skyddad endpoint som endast administratörer har tillgång till.
+
+10. Krav: Ett meddelande ska vara minst 3 och max 140 tecken.
+
+Implementerat. Se ändringar i server.js, message.js, samt singlemessage.jsx och postmessage.jsx
\ No newline at end of file
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index a16cbde4..011e67c7 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -11,7 +11,7 @@ export const App = () => {
const [modal, setModal] = useState(null)
const [error, setError] = useState(null)
- //nedan är ny fetchPosts variabel. När vi la till authenticateUser på GET /messages i backenden som en del av säkerhetskrav 3, att endast inloggade ska kunna se meddelanden, behövde frontenden också skicka med JWT-token i varje anrop, annars svarar backenden med 401 och inga meddelanden visas. Funktionen hämtar nu meddelanden från backenden och skickar med en Authorization-header som innehåller användarens JWT-token. Backenden använder token för att verifiera att användaren är inloggad innan den returnerar meddelandena. Utan token blockeras anropet av authenticateUser-middleware och inga meddelanden skickas tillbaka.
+ //Säkerhetskrav 3: Nedan är ny fetchPosts variabel. När vi la till authenticateUser på GET /messages i backenden som en del av säkerhetskrav 3, att endast inloggade ska kunna se meddelanden, behövde frontenden också skicka med JWT-token i varje anrop, annars svarar backenden med 401 och inga meddelanden visas. Funktionen hämtar nu meddelanden från backenden och skickar med en Authorization-header som innehåller användarens JWT-token. Backenden använder token för att verifiera att användaren är inloggad innan den returnerar meddelandena. Utan token blockeras anropet av authenticateUser-middleware och inga meddelanden skickas tillbaka.
const fetchPosts = () => {
setLoading(true)
fetch(`${BASE_URL}/messages`, {
@@ -29,7 +29,7 @@ export const App = () => {
if (user) fetchPosts()
}, [user])
- // ovan har gjorts om för att endast inloggade användare ska kunna se meddelanden. Nedan är den tidigare versionen där fetchPosts kördes varje gång appen laddades, oavsett om en användare var inloggad eller inte. Det är en del av mitt säkerhetskrav 4, alltså att endast autentiserade användare ska kunna se meddelanden.
+ // Säkerhetskrav 3. Ovan har gjorts om för att endast inloggade användare ska kunna se meddelanden. Nedan är den tidigare versionen där fetchPosts kördes varje gång appen laddades, oavsett om en användare var inloggad eller inte.
//useEffect(() => {
// fetchPosts()
// }, [])
@@ -92,6 +92,6 @@ export const App = () => {
user={user}
onUnauthorized={handleUnauthorized}
/>}
- > //La till {user && så att Messagelist bara renderas om användaren är inloggad, så att ej autentiserade användare inte kan se meddelanden — del av säkerhetskrav 3
+ > //Säkerhetskrav 3: La till {user && så att Messagelist bara renderas om användaren är inloggad, så att icke-autentiserade användare inte kan se meddelanden.
)
}
diff --git a/frontend/src/api.js b/frontend/src/api.js
index 73caeaf6..87ce50fe 100644
--- a/frontend/src/api.js
+++ b/frontend/src/api.js
@@ -1,4 +1,5 @@
export const BASE_URL = "http://localhost:3000"
-//export const BASE_URL = "https://yh-message-app-fullstack.onrender.com"
-//den gamla!
\ No newline at end of file
+//BASE_URL är ändrad till localhost för utveckling. när projektet ska deployas är det viktigt att url:n är en https://-adress för att uppfylla säkerhetskrav 8.
+
+// den tidigare adressen: export const BASE_URL = "https://yh-message-app-fullstack.onrender.com"
diff --git a/frontend/src/components/PostMessage.jsx b/frontend/src/components/PostMessage.jsx
index 4345e5db..310a1877 100644
--- a/frontend/src/components/PostMessage.jsx
+++ b/frontend/src/components/PostMessage.jsx
@@ -10,7 +10,7 @@ export const PostMessage = ({ newMessage, fetchPosts, user, onUnauthorized }) =>
event.preventDefault()
setSubmitting(true)
- // detta sätts in för att validera i frontenden att meddelandet som postas är mellan 3 och 140 tecken, säkerhetskrav 10.
+ // Säkerhetskrav 10. Detta sätts in för att validera i frontenden att meddelandet som postas är mellan 3 och 140 tecken.
if (newPost.length < 3 || newPost.length > 140) {
setErrorMessage("Message must be between 3 and 140 characters")
setSubmitting(false)
@@ -58,7 +58,7 @@ export const PostMessage = ({ newMessage, fetchPosts, user, onUnauthorized }) =>
if (!user) {
return Log in to see and write messages
- } // Om man inte är inloggad renderas inte formuläret för att skriva meddelanden. Meddelandet ändrat för att förtydliga att användaren måste logga in för att både se och skriva meddelanden. säkerhetskrav 3.
+ } //Säkerhetskrav 3. Denna kodrad gör att formuläret för att skriva ett meddelande inte renderas om man inte är inloggad. Meddelandet som visas har jag ändrat för att förtydliga att användaren måste logga in för att både se och skriva meddelanden.
return (
diff --git a/frontend/src/components/SingleMessage.jsx b/frontend/src/components/SingleMessage.jsx
index 11fa4be8..cb4614b4 100644
--- a/frontend/src/components/SingleMessage.jsx
+++ b/frontend/src/components/SingleMessage.jsx
@@ -29,7 +29,7 @@ export const SingleMessage = ({ message, user, onUnauthorized, fetchPosts }) =>
}
const onSave = async () => {
- //lägger här in validering i frontenden att meddelande som redigeras måste vara mellan 3 och 140 tecken. säkerhetskrav 10.
+ //säkerhetskrav 10. Lägger här in validering i frontenden att meddelande som redigeras måste vara mellan 3 och 140 tecken.
if (editedText.length < 3 || editedText.length > 140) {
setEditError("Message must be between 3 and 140 characters")
return
@@ -87,12 +87,12 @@ export const SingleMessage = ({ message, user, onUnauthorized, fetchPosts }) =>
)}
- {/* för att endast ägaren av meddelandet ska kunna radera har isOwner lagts till som villkor på deleteknappen. Då visas den inte för andra användare, vilket är en del av mitt säkerhetskrav 4. */}
+ {/* Säkerhetskrav 4. För att endast ägaren av meddelandet ska kunna radera har isOwner lagts till som villkor på deleteknappen. Det gör att delete-knappen bara visas för användare som äger meddelandet. Kosmetisk del, det riktiga skyddet sitter i backend. */}
{isOwner && 🗑️ }
{isOwner && !isEditing && (
- setIsEditing(true)}>✏️ // “edit”-knappen dyker bara upp för den som är inloggad och äger meddelandet. Detta var redan med från början. Säkerhetskrav 3 och 4.
+ setIsEditing(true)}>✏️ // Säkerhetskrav 4. “Edit”-knappen dyker bara upp för den som är inloggad och äger meddelandet (geno isOWner) Detta var med i koden redan från början.
)}
{isOwner && isEditing && (
From 9bfae0dab6f8a6d7a77af7983722fc208448a161 Mon Sep 17 00:00:00 2001
From: karinisaksson <152193321+karinisaksson@users.noreply.github.com>
Date: Mon, 8 Jun 2026 16:02:06 +0200
Subject: [PATCH 22/40] fixade stavfel
---
fas2.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fas2.md b/fas2.md
index 7f1917d4..0f627eac 100644
--- a/fas2.md
+++ b/fas2.md
@@ -38,7 +38,7 @@ Detta la jag till genom rate-limiting. Se ny middleware i rateLimiter.js och anv
7. Krav: För att återställa lösenord krävs en engångskod skickad till användarens e-post.
-För att implementera lösenordsåterställning via engångskod behövs flera delar. För det första behövs e funktion för att återställa lösenordet, samt en e-posttjänst, till exempel Nodemailer, som kan skicka ett e-postmeddelande med en engångskod till användaren.
+För att implementera lösenordsåterställning via engångskod behövs flera delar. För det första behövs en funktion för att återställa lösenordet, samt en e-posttjänst, till exempel Nodemailer, som kan skicka ett e-postmeddelande med en engångskod till användaren.
Implementationen skulle börja med en POST /forgot-password-route som tar emot användarens e-postadress, genererar en tidsbegränsad engångskod och skickar den till användaren via e-post med exempelvis Nodemailer.
@@ -49,9 +49,9 @@ Därefter behövs en POST /reset-password-route där användaren anger koden til
8. Krav: All kommunikation ska vara krypterad via HTTPS och TLS.
-För att anropen ska ske via HTTPS är det viktigt att BASE_URL i api.js pekar mot en https-adress. Just nu är URL:n i api.js en lokal host för utveckling, som går över http, men i produktion måste det vara en HTTPS-adress för att uppfylla säkerhetskravet-
+För att anropen ska ske via HTTPS är det viktigt att BASE_URL i api.js pekar mot en https-adress. Just nu är URL:n i api.js en lokal host för utveckling, som går över http, men i produktion måste det vara en HTTPS-adress för att uppfylla säkerhetskravet.
-För att kommunikationen ska vara krypterad enligt TLS behöver vi skaffa ett TLS-certifikat, och en reverse-proxy som tar emot https-anrop, dekrypterar och vidarebefordrar anropen till min vår express-server.
+För att kommunikationen ska vara krypterad enligt TLS behöver vi skaffa ett TLS-certifikat. Det fixas inte i koden utan när vi deployar.
9. Systemet ska logga vem som skapade, redigerade och raderade varje meddelande.
@@ -61,4 +61,4 @@ Loggarna nås direkt i databasen via MongoDB Compass eller MongoDB Atlas av den
10. Krav: Ett meddelande ska vara minst 3 och max 140 tecken.
-Implementerat. Se ändringar i server.js, message.js, samt singlemessage.jsx och postmessage.jsx
\ No newline at end of file
+Implementerat. Se ändringar i server.js, message.js, samt singlemessage.jsx och postmessage.jsx
From 63fe4e63ace4f3c37f5ee1379f50d45d792c5d4a Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Mon, 8 Jun 2026 16:04:17 +0200
Subject: [PATCH 23/40] =?UTF-8?q?f=C3=B6rtydligande?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
backend/server.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/server.js b/backend/server.js
index 066e277c..c903fa2c 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -20,7 +20,7 @@ const PORT = process.env.PORT || "3000"
const app = express()
app.use(helmet())
app.use(cors({
- origin: "*", // app.use inställt med stjärnan som origin innebär att alla domäner på internet kan skicka requests till min API. Det kan blir ett säkerhetsproblem, och är dålig praxis i produktion.
+ origin: "*", //Extra: app.use(cors inställt med * som origin innebär att alla domäner på internet kan skicka requests till min API. Det kan bli ett säkerhetsproblem, och är dålig praxis i produktion.
// bör ändras till app.use(cors({origin: min-frontends-url}))
}))
From d0d463e0e2be216484c3062cc5ed4ecfae4583d3 Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Mon, 8 Jun 2026 16:11:07 +0200
Subject: [PATCH 24/40] =?UTF-8?q?f=C3=B6rtyligande=20krav=201?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
backend/server.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/server.js b/backend/server.js
index c903fa2c..31ff5f72 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -25,7 +25,7 @@ app.use(cors({
}))
app.use(express.json())
-app.use(mongoSanitize()) //Säkerhetskrav 1. Här används mongoSanitize för att sanera input och skydda mot NoSQL-injection.
+app.use(mongoSanitize()) //Säkerhetskrav 1. Här används mongoSanitize för att sanera input och skydda mot NoSQL-injection. Vilket innebär att all inkommande request-data (body, params, query) automatiskt rensas från MongoDB-operatorer som $ och . innan de når någon route.
app.get("/", (req, res) => {
res.send(listEndpoints(app))
From 514593eec0bce9b6a5a00c7a6c6425a570773320 Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Tue, 9 Jun 2026 12:57:25 +0200
Subject: [PATCH 25/40] =?UTF-8?q?fas=203:=20=C3=A5tg=C3=A4rdade=20s=C3=A5r?=
=?UTF-8?q?barheter=20med=20ratelimiter?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
backend/middleware/rateLimiter.js | 10 +++++++++-
backend/server.js | 20 +++++++++++++-------
2 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/backend/middleware/rateLimiter.js b/backend/middleware/rateLimiter.js
index 6376d825..86886a60 100644
--- a/backend/middleware/rateLimiter.js
+++ b/backend/middleware/rateLimiter.js
@@ -6,4 +6,12 @@ export const loginLimiter = rateLimit({
message: { success: false, message: "Too many login attempts, please try again after 15 minutes" }
})
-// Säkerhetskrav 6. Här har jag lagt in en funktion LoginLimiter som använder express-rate-limit för att begränsa antalet inloggningsförsök till 5 per 15 minuter. Sedan använder jag loginLimiter som middleware i server.js: app.post("/login") för att tillämpa denna begränsning på inloggningsförsöken.
\ No newline at end of file
+// Säkerhetskrav 6. Här har jag lagt in en funktion LoginLimiter som använder express-rate-limit för att begränsa antalet inloggningsförsök till 5 per 15 minuter. Sedan använder jag loginLimiter som middleware i server.js: app.post("/login") för att tillämpa denna begränsning på inloggningsförsöken.
+
+
+// Efter att ha använt CodeQL och hittat sårbarheter att jag en till limiter för att använda på övriga endpoints som gör databasanrop utan någon begränsning. Annars kan en angripare skicka tusentals requests per sekund och överlasta databas/server.
+export const generalLimiter = rateLimit({
+ windowMs: 15 * 60 * 1000, // 15 minuter
+ max: 100, // 100 requests per 15 min per IP
+ message: { success: false, message: "Too many requests, please try again later" }
+})
\ No newline at end of file
diff --git a/backend/server.js b/backend/server.js
index 31ff5f72..e0df2849 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -10,8 +10,9 @@ import { User } from "./models/User.js"
import { authenticateUser } from "./middleware/auth.js"
import "./config/db.js"
import listEndpoints from "express-list-endpoints"
-import { loginLimiter } from "./middleware/rateLimiter.js"
-// Säkerhetskrav 6: Importerar middlewaren loginLimiter
+import { loginLimiter, generalLimiter } from "./middleware/rateLimiter.js"
+// Säkerhetskrav 6: Importerar middlewaren loginLimiter
+//fas 3: importerar även nya ratelimitern generalLimiter
import mongoSanitize from "express-mongo-sanitize" //Säkerhetskrav 1: Importerar för att sanera input och skydda mot NoSQL-injection.
if (!process.env.JWT_SECRET) throw new Error("JWT_SECRET is not set in .env")
@@ -31,7 +32,8 @@ app.get("/", (req, res) => {
res.send(listEndpoints(app))
})
-app.post("/register", async (req, res) => {
+//applicerar generalLimiter
+app.post("/register", generalLimiter, async (req, res) => {
try {
const { email, password, username } = req.body
@@ -133,7 +135,8 @@ app.post("/login", loginLimiter, async (req, res) => {
const isValidId = (id) => mongoose.Types.ObjectId.isValid(id)
//Säkerhetskrav 3. Lagt till middlewaren authenticateUser så att endast inloggade användare kan se meddelanden.
-app.get("/messages", authenticateUser, async (req, res) => {
+// fas 3: lägger till generalLimiter
+app.get("/messages", authenticateUser, generalLimiter, async (req, res) => {
try {
const messages = await Message.find()
.sort({ createdAt: "desc" })
@@ -146,7 +149,8 @@ app.get("/messages", authenticateUser, async (req, res) => {
}
})
//Säkerhetskrav 3. authenticateUser finns med i app.post, vilket gör att inloggning krävs för att posta ett meddelande. Detta fanns redan med i koden från början.
-app.post("/messages", authenticateUser, async (req, res) => {
+//fas 3: lägger till generalLimiter
+app.post("/messages", authenticateUser, generalLimiter, async (req, res) => {
const text = req.body.message
if (!text || text.length < 3 || text.length > 140) {
return res.status(400).json({ message: "Message must be between 3 and 140 characters" }) // Säkerhetskrav 10. Ändrat begränsning av längd på meddelanden.
@@ -161,7 +165,8 @@ app.post("/messages", authenticateUser, async (req, res) => {
})
//Säkerhetskrav 3: Att authenicateUser finns med i app.patch(“/messages/:id gör att det krävs att man är inloggad för att redigera ett meddelande. Detta fanns med i koden från början.
-app.patch("/messages/:id", authenticateUser, async (req, res) => {
+//fas 3: lägger till generalLimiter
+app.patch("/messages/:id", authenticateUser, generalLimiter, async (req, res) => {
if (!isValidId(req.params.id)) return res.status(400).json({ error: "Invalid message ID" })
try {
const message = await Message.findById(req.params.id)
@@ -187,7 +192,8 @@ app.patch("/messages/:id", authenticateUser, async (req, res) => {
})
// Säkerhetskrav 3/4: La till authenticateUser vid radering av meddelande, vilket gör att man måste vara inloggad för att ändra meddelande.
-app.delete("/messages/:id", authenticateUser, async (req, res) => {
+//fas 3: lägger till generalLimiter
+app.delete("/messages/:id", authenticateUser, generalLimiter, async (req, res) => {
if (!isValidId(req.params.id)) return res.status(400).json({ error: "Invalid message ID" })
try {
const message = await Message.findById(req.params.id)
From 104e2f087f4ac0c82a1d100d3889fbf92402ce93 Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Tue, 9 Jun 2026 13:02:45 +0200
Subject: [PATCH 26/40] =?UTF-8?q?fas=203:=20f=C3=B6rtdligade=20generalLimi?=
=?UTF-8?q?ter?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
backend/middleware/rateLimiter.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/backend/middleware/rateLimiter.js b/backend/middleware/rateLimiter.js
index 86886a60..3b786bd4 100644
--- a/backend/middleware/rateLimiter.js
+++ b/backend/middleware/rateLimiter.js
@@ -6,10 +6,10 @@ export const loginLimiter = rateLimit({
message: { success: false, message: "Too many login attempts, please try again after 15 minutes" }
})
-// Säkerhetskrav 6. Här har jag lagt in en funktion LoginLimiter som använder express-rate-limit för att begränsa antalet inloggningsförsök till 5 per 15 minuter. Sedan använder jag loginLimiter som middleware i server.js: app.post("/login") för att tillämpa denna begränsning på inloggningsförsöken.
+// Säkerhetskrav 6. Här har jag lagt in en funktion loginLimiter som använder express-rate-limit för att begränsa antalet inloggningsförsök till 5 per 15 minuter. Sedan använder jag loginLimiter som middleware i server.js: app.post("/login") för att tillämpa denna begränsning på inloggningsförsöken.
-// Efter att ha använt CodeQL och hittat sårbarheter att jag en till limiter för att använda på övriga endpoints som gör databasanrop utan någon begränsning. Annars kan en angripare skicka tusentals requests per sekund och överlasta databas/server.
+// Efter att ha använt CodeQL och hittat sårbarheter la jag till ytterligare en limiter för att använda på övriga endpoints som gör databasanrop. Annars kan en angripare skicka tusentals requests per sekund och överlasta databas/server. Satte ett högre tak än loginLimiter eftersom 5 anrop på 15 minuter skulle göra appen oanvändbar på tex /messages GET/POST/PATCH/DELETE.
export const generalLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minuter
max: 100, // 100 requests per 15 min per IP
From dedd1e7fe114c876c9ba4d598faa4e3b8187487f Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Tue, 9 Jun 2026 13:09:59 +0200
Subject: [PATCH 27/40] =?UTF-8?q?fas=203:=20generalLimiter=20i=20r=C3=A4tt?=
=?UTF-8?q?=20ordning?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
backend/server.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/backend/server.js b/backend/server.js
index e0df2849..4ca68bd2 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -136,7 +136,7 @@ const isValidId = (id) => mongoose.Types.ObjectId.isValid(id)
//Säkerhetskrav 3. Lagt till middlewaren authenticateUser så att endast inloggade användare kan se meddelanden.
// fas 3: lägger till generalLimiter
-app.get("/messages", authenticateUser, generalLimiter, async (req, res) => {
+app.get("/messages", generalLimiter, authenticateUser, async (req, res) => {
try {
const messages = await Message.find()
.sort({ createdAt: "desc" })
@@ -150,7 +150,7 @@ app.get("/messages", authenticateUser, generalLimiter, async (req, res) => {
})
//Säkerhetskrav 3. authenticateUser finns med i app.post, vilket gör att inloggning krävs för att posta ett meddelande. Detta fanns redan med i koden från början.
//fas 3: lägger till generalLimiter
-app.post("/messages", authenticateUser, generalLimiter, async (req, res) => {
+app.post("/messages", generalLimiter, authenticateUser, async (req, res) => {
const text = req.body.message
if (!text || text.length < 3 || text.length > 140) {
return res.status(400).json({ message: "Message must be between 3 and 140 characters" }) // Säkerhetskrav 10. Ändrat begränsning av längd på meddelanden.
@@ -166,7 +166,7 @@ app.post("/messages", authenticateUser, generalLimiter, async (req, res) => {
//Säkerhetskrav 3: Att authenicateUser finns med i app.patch(“/messages/:id gör att det krävs att man är inloggad för att redigera ett meddelande. Detta fanns med i koden från början.
//fas 3: lägger till generalLimiter
-app.patch("/messages/:id", authenticateUser, generalLimiter, async (req, res) => {
+app.patch("/messages/:id", generalLimiter, authenticateUser, async (req, res) => {
if (!isValidId(req.params.id)) return res.status(400).json({ error: "Invalid message ID" })
try {
const message = await Message.findById(req.params.id)
@@ -193,7 +193,7 @@ app.patch("/messages/:id", authenticateUser, generalLimiter, async (req, res) =>
// Säkerhetskrav 3/4: La till authenticateUser vid radering av meddelande, vilket gör att man måste vara inloggad för att ändra meddelande.
//fas 3: lägger till generalLimiter
-app.delete("/messages/:id", authenticateUser, generalLimiter, async (req, res) => {
+app.delete("/messages/:id", generalLimiter, authenticateUser, async (req, res) => {
if (!isValidId(req.params.id)) return res.status(400).json({ error: "Invalid message ID" })
try {
const message = await Message.findById(req.params.id)
From 85337554ba2d77f95f0ad0a633c2ad87b9685a9a Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Tue, 9 Jun 2026 13:20:15 +0200
Subject: [PATCH 28/40] fas 3: CORS-config
---
backend/server.js | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/backend/server.js b/backend/server.js
index 4ca68bd2..fcef780e 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -20,11 +20,12 @@ if (!process.env.JWT_SECRET) throw new Error("JWT_SECRET is not set in .env")
const PORT = process.env.PORT || "3000"
const app = express()
app.use(helmet())
+// app.use(cors({
+// origin: "*"
app.use(cors({
- origin: "*", //Extra: app.use(cors inställt med * som origin innebär att alla domäner på internet kan skicka requests till min API. Det kan bli ett säkerhetsproblem, och är dålig praxis i produktion.
- // bör ändras till app.use(cors({origin: min-frontends-url}))
+ origin: "http://localhost:5173",
+})) // fas 3: ändrat så att bara frontend får skicka requests till API/backend. När det var * som origin kunde vilken domän som helst skicka requests till min backend. Hittade detta själv men åtgärdade i fas 3 efter att även CodeQL påpekat det.
-}))
app.use(express.json())
app.use(mongoSanitize()) //Säkerhetskrav 1. Här används mongoSanitize för att sanera input och skydda mot NoSQL-injection. Vilket innebär att all inkommande request-data (body, params, query) automatiskt rensas från MongoDB-operatorer som $ och . innan de når någon route.
From d10ec93e3580eb3d9de3a54fe2a1b533299c6d84 Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Tue, 9 Jun 2026 14:18:48 +0200
Subject: [PATCH 29/40] =?UTF-8?q?fas=203:=20generallimiter=20p=C3=A5=20all?=
=?UTF-8?q?a=20endpoints?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
backend/server.js | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/backend/server.js b/backend/server.js
index fcef780e..e9bd4d34 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -25,16 +25,15 @@ app.use(helmet())
app.use(cors({
origin: "http://localhost:5173",
})) // fas 3: ändrat så att bara frontend får skicka requests till API/backend. När det var * som origin kunde vilken domän som helst skicka requests till min backend. Hittade detta själv men åtgärdade i fas 3 efter att även CodeQL påpekat det.
-
app.use(express.json())
app.use(mongoSanitize()) //Säkerhetskrav 1. Här används mongoSanitize för att sanera input och skydda mot NoSQL-injection. Vilket innebär att all inkommande request-data (body, params, query) automatiskt rensas från MongoDB-operatorer som $ och . innan de når någon route.
+app.use(generalLimiter) // fas 3: använder generalLimiter globalt på alla endpoints, vilket gör att alla nya rutter skyddas automatiskt istället för att lägga till limitern manuellt vid varje ny endpoint.
app.get("/", (req, res) => {
res.send(listEndpoints(app))
})
-//applicerar generalLimiter
-app.post("/register", generalLimiter, async (req, res) => {
+app.post("/register", async (req, res) => {
try {
const { email, password, username } = req.body
@@ -136,8 +135,7 @@ app.post("/login", loginLimiter, async (req, res) => {
const isValidId = (id) => mongoose.Types.ObjectId.isValid(id)
//Säkerhetskrav 3. Lagt till middlewaren authenticateUser så att endast inloggade användare kan se meddelanden.
-// fas 3: lägger till generalLimiter
-app.get("/messages", generalLimiter, authenticateUser, async (req, res) => {
+app.get("/messages", authenticateUser, async (req, res) => {
try {
const messages = await Message.find()
.sort({ createdAt: "desc" })
@@ -150,8 +148,7 @@ app.get("/messages", generalLimiter, authenticateUser, async (req, res) => {
}
})
//Säkerhetskrav 3. authenticateUser finns med i app.post, vilket gör att inloggning krävs för att posta ett meddelande. Detta fanns redan med i koden från början.
-//fas 3: lägger till generalLimiter
-app.post("/messages", generalLimiter, authenticateUser, async (req, res) => {
+app.post("/messages", authenticateUser, async (req, res) => {
const text = req.body.message
if (!text || text.length < 3 || text.length > 140) {
return res.status(400).json({ message: "Message must be between 3 and 140 characters" }) // Säkerhetskrav 10. Ändrat begränsning av längd på meddelanden.
@@ -166,8 +163,7 @@ app.post("/messages", generalLimiter, authenticateUser, async (req, res) => {
})
//Säkerhetskrav 3: Att authenicateUser finns med i app.patch(“/messages/:id gör att det krävs att man är inloggad för att redigera ett meddelande. Detta fanns med i koden från början.
-//fas 3: lägger till generalLimiter
-app.patch("/messages/:id", generalLimiter, authenticateUser, async (req, res) => {
+app.patch("/messages/:id", authenticateUser, async (req, res) => {
if (!isValidId(req.params.id)) return res.status(400).json({ error: "Invalid message ID" })
try {
const message = await Message.findById(req.params.id)
@@ -193,8 +189,7 @@ app.patch("/messages/:id", generalLimiter, authenticateUser, async (req, res) =>
})
// Säkerhetskrav 3/4: La till authenticateUser vid radering av meddelande, vilket gör att man måste vara inloggad för att ändra meddelande.
-//fas 3: lägger till generalLimiter
-app.delete("/messages/:id", generalLimiter, authenticateUser, async (req, res) => {
+app.delete("/messages/:id", authenticateUser, async (req, res) => {
if (!isValidId(req.params.id)) return res.status(400).json({ error: "Invalid message ID" })
try {
const message = await Message.findById(req.params.id)
From b04b5085a16fea1022ca835b8e912a11f20c0466 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 9 Jun 2026 20:57:31 +0000
Subject: [PATCH 30/40] Bump jsonwebtoken from 8.5.1 to 9.0.0 in /backend
Bumps [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) from 8.5.1 to 9.0.0.
- [Changelog](https://github.com/auth0/node-jsonwebtoken/blob/master/CHANGELOG.md)
- [Commits](https://github.com/auth0/node-jsonwebtoken/compare/v8.5.1...v9.0.0)
---
updated-dependencies:
- dependency-name: jsonwebtoken
dependency-version: 9.0.0
dependency-type: direct:production
...
Signed-off-by: dependabot[bot]
---
backend/package-lock.json | 113 +++++++-------------------------------
backend/package.json | 2 +-
2 files changed, 20 insertions(+), 95 deletions(-)
diff --git a/backend/package-lock.json b/backend/package-lock.json
index 90e93b82..f5c0dd44 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -16,7 +16,7 @@
"express-mongo-sanitize": "^2.2.0",
"express-rate-limit": "^8.5.2",
"helmet": "^7.1.0",
- "jsonwebtoken": "8.5.1",
+ "jsonwebtoken": "9.0.0",
"mongoose": "^8.4.0",
"nodemon": "^3.1.3"
}
@@ -41,18 +41,6 @@
"node-pre-gyp": "bin/node-pre-gyp"
}
},
- "node_modules/@mapbox/node-pre-gyp/node_modules/semver": {
- "version": "7.8.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz",
- "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@mongodb-js/saslprep": {
"version": "1.4.11",
"resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.11.tgz",
@@ -1089,25 +1077,19 @@
}
},
"node_modules/jsonwebtoken": {
- "version": "8.5.1",
- "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
- "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
+ "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
"license": "MIT",
"dependencies": {
"jws": "^3.2.2",
- "lodash.includes": "^4.3.0",
- "lodash.isboolean": "^3.0.3",
- "lodash.isinteger": "^4.0.4",
- "lodash.isnumber": "^3.0.3",
- "lodash.isplainobject": "^4.0.6",
- "lodash.isstring": "^4.0.1",
- "lodash.once": "^4.0.0",
+ "lodash": "^4.17.21",
"ms": "^2.1.1",
- "semver": "^5.6.0"
+ "semver": "^7.3.8"
},
"engines": {
- "node": ">=4",
- "npm": ">=1.4.28"
+ "node": ">=12",
+ "npm": ">=6"
}
},
"node_modules/jsonwebtoken/node_modules/ms": {
@@ -1146,46 +1128,10 @@
"node": ">=12.0.0"
}
},
- "node_modules/lodash.includes": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
- "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
- "license": "MIT"
- },
- "node_modules/lodash.isboolean": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
- "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
- "license": "MIT"
- },
- "node_modules/lodash.isinteger": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
- "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
- "license": "MIT"
- },
- "node_modules/lodash.isnumber": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
- "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
- "license": "MIT"
- },
- "node_modules/lodash.isplainobject": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
- "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
- "license": "MIT"
- },
- "node_modules/lodash.isstring": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
- "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
- "license": "MIT"
- },
- "node_modules/lodash.once": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
- "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
+ "node_modules/lodash": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
"license": "MIT"
},
"node_modules/make-dir": {
@@ -1590,18 +1536,6 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
- "node_modules/nodemon/node_modules/semver": {
- "version": "7.8.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz",
- "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
@@ -1853,12 +1787,15 @@
"license": "MIT"
},
"node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.3.tgz",
+ "integrity": "sha512-wnilbGyMxzbY7dNOl7jpKbLSjcfeweJWU5j4+u5qW+6/wuGD9KzIGOyZnQVSBM9E7DtWaaH3CyHkppYrKYoxwg==",
"license": "ISC",
"bin": {
- "semver": "bin/semver"
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/send": {
@@ -2014,18 +1951,6 @@
"node": ">=10"
}
},
- "node_modules/simple-update-notifier/node_modules/semver": {
- "version": "7.8.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz",
- "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
diff --git a/backend/package.json b/backend/package.json
index 1c17c054..6800df1b 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -17,7 +17,7 @@
"express-mongo-sanitize": "^2.2.0",
"express-rate-limit": "^8.5.2",
"helmet": "^7.1.0",
- "jsonwebtoken": "8.5.1",
+ "jsonwebtoken": "9.0.0",
"mongoose": "^8.4.0",
"nodemon": "^3.1.3"
}
From a6e2d1ab0c0653d3a9732fcde3a131053fdbd0b5 Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Wed, 10 Jun 2026 00:51:58 +0200
Subject: [PATCH 31/40] =?UTF-8?q?fas=203:=20uppdaterade=20bcrypt=20till=20?=
=?UTF-8?q?v6=20to=20f=C3=B6r=20att=20ta=20bort=20tar-dependency?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
backend/package-lock.json | 607 ++------------------------------------
backend/package.json | 2 +-
2 files changed, 20 insertions(+), 589 deletions(-)
diff --git a/backend/package-lock.json b/backend/package-lock.json
index f5c0dd44..35834289 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -8,7 +8,7 @@
"name": "yh-message-app-fullstack",
"version": "1.0.0",
"dependencies": {
- "bcrypt": "^5.1.1",
+ "bcrypt": "^6.0.0",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
@@ -21,26 +21,6 @@
"nodemon": "^3.1.3"
}
},
- "node_modules/@mapbox/node-pre-gyp": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
- "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "detect-libc": "^2.0.0",
- "https-proxy-agent": "^5.0.0",
- "make-dir": "^3.1.0",
- "node-fetch": "^2.6.7",
- "nopt": "^5.0.0",
- "npmlog": "^5.0.1",
- "rimraf": "^3.0.2",
- "semver": "^7.3.5",
- "tar": "^6.1.11"
- },
- "bin": {
- "node-pre-gyp": "bin/node-pre-gyp"
- }
- },
"node_modules/@mongodb-js/saslprep": {
"version": "1.4.11",
"resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.11.tgz",
@@ -65,12 +45,6 @@
"@types/webidl-conversions": "*"
}
},
- "node_modules/abbrev": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
- "license": "ISC"
- },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -84,50 +58,6 @@
"node": ">= 0.6"
}
},
- "node_modules/agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "4"
- },
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/agent-base/node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/agent-base/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
@@ -141,26 +71,6 @@
"node": ">= 8"
}
},
- "node_modules/aproba": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz",
- "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==",
- "license": "ISC"
- },
- "node_modules/are-we-there-yet": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
- "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
- "deprecated": "This package is no longer supported.",
- "license": "ISC",
- "dependencies": {
- "delegates": "^1.0.0",
- "readable-stream": "^3.6.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
@@ -177,17 +87,17 @@
}
},
"node_modules/bcrypt": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz",
- "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-6.0.0.tgz",
+ "integrity": "sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
- "@mapbox/node-pre-gyp": "^1.0.11",
- "node-addon-api": "^5.0.0"
+ "node-addon-api": "^8.3.0",
+ "node-gyp-build": "^4.8.4"
},
"engines": {
- "node": ">= 10.0.0"
+ "node": ">= 18"
}
},
"node_modules/binary-extensions": {
@@ -327,36 +237,6 @@
"fsevents": "~2.3.2"
}
},
- "node_modules/chownr": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
- "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
- "license": "ISC",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/color-support": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
- "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
- "license": "ISC",
- "bin": {
- "color-support": "bin.js"
- }
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "license": "MIT"
- },
- "node_modules/console-control-strings": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
- "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
- "license": "ISC"
- },
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@@ -419,12 +299,6 @@
"ms": "2.0.0"
}
},
- "node_modules/delegates": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
- "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
- "license": "MIT"
- },
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -444,15 +318,6 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
- "node_modules/detect-libc": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/dotenv": {
"version": "16.6.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
@@ -494,12 +359,6 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"license": "MIT"
},
- "node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "license": "MIT"
- },
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
@@ -684,36 +543,6 @@
"node": ">= 0.6"
}
},
- "node_modules/fs-minipass": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
- "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
- "license": "ISC",
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/fs-minipass/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "license": "ISC",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "license": "ISC"
- },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -737,27 +566,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/gauge": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
- "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
- "deprecated": "This package is no longer supported.",
- "license": "ISC",
- "dependencies": {
- "aproba": "^1.0.3 || ^2.0.0",
- "color-support": "^1.1.2",
- "console-control-strings": "^1.0.0",
- "has-unicode": "^2.0.1",
- "object-assign": "^4.1.1",
- "signal-exit": "^3.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1",
- "wide-align": "^1.1.2"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
@@ -795,27 +603,6 @@
"node": ">= 0.4"
}
},
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@@ -828,34 +615,6 @@
"node": ">= 6"
}
},
- "node_modules/glob/node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "license": "MIT"
- },
- "node_modules/glob/node_modules/brace-expansion": {
- "version": "1.1.14",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz",
- "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==",
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/glob/node_modules/minimatch": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
- "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -889,12 +648,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/has-unicode": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
- "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
- "license": "ISC"
- },
"node_modules/hasown": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz",
@@ -936,42 +689,6 @@
"url": "https://opencollective.com/express"
}
},
- "node_modules/https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/https-proxy-agent/node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/https-proxy-agent/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -990,17 +707,6 @@
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
"license": "ISC"
},
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
- "license": "ISC",
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@@ -1046,15 +752,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@@ -1134,30 +831,6 @@
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
"license": "MIT"
},
- "node_modules/make-dir": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
- "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
- "license": "MIT",
- "dependencies": {
- "semver": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/make-dir/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -1248,52 +921,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/minipass": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
- "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
- "license": "ISC",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/minizlib": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
- "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
- "license": "MIT",
- "dependencies": {
- "minipass": "^3.0.0",
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/minizlib/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "license": "ISC",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "license": "MIT",
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/mongodb": {
"version": "6.20.0",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.20.0.tgz",
@@ -1438,51 +1065,23 @@
}
},
"node_modules/node-addon-api": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
- "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==",
- "license": "MIT"
- },
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.8.0.tgz",
+ "integrity": "sha512-c5Ko1fZJIJmzhFIkhRN76WTq+fC6tWnGy9CXA0fA+XygsWZmEwG8vmbkNqxMyoaa0Tin4djul49NzdVcJJcjeA==",
"license": "MIT",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
"engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
+ "node": "^18 || ^20 || >= 21"
}
},
- "node_modules/node-fetch/node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
- "license": "MIT"
- },
- "node_modules/node-fetch/node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "license": "BSD-2-Clause"
- },
- "node_modules/node-fetch/node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "node_modules/node-gyp-build": {
+ "version": "4.8.4",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
+ "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
"license": "MIT",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
+ "bin": {
+ "node-gyp-build": "bin.js",
+ "node-gyp-build-optional": "optional.js",
+ "node-gyp-build-test": "build-test.js"
}
},
"node_modules/nodemon": {
@@ -1536,21 +1135,6 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
- "node_modules/nopt": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
- "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
- "license": "ISC",
- "dependencies": {
- "abbrev": "1"
- },
- "bin": {
- "nopt": "bin/nopt.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -1560,19 +1144,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/npmlog": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
- "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
- "deprecated": "This package is no longer supported.",
- "license": "ISC",
- "dependencies": {
- "are-we-there-yet": "^2.0.0",
- "console-control-strings": "^1.1.0",
- "gauge": "^3.0.0",
- "set-blocking": "^2.0.0"
- }
- },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -1606,15 +1177,6 @@
"node": ">= 0.8"
}
},
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -1624,15 +1186,6 @@
"node": ">= 0.8"
}
},
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/path-to-regexp": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
@@ -1718,20 +1271,6 @@
"node": ">= 0.8"
}
},
- "node_modules/readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -1744,22 +1283,6 @@
"node": ">=8.10.0"
}
},
- "node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -1843,12 +1366,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/set-blocking": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
- "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
- "license": "ISC"
- },
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -1933,12 +1450,6 @@
"integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==",
"license": "MIT"
},
- "node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "license": "ISC"
- },
"node_modules/simple-update-notifier": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
@@ -1969,41 +1480,6 @@
"node": ">= 0.8"
}
},
- "node_modules/string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "~5.2.0"
- }
- },
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -2016,24 +1492,6 @@
"node": ">=4"
}
},
- "node_modules/tar": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
- "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
- "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
- "license": "ISC",
- "dependencies": {
- "chownr": "^2.0.0",
- "fs-minipass": "^2.0.0",
- "minipass": "^5.0.0",
- "minizlib": "^2.1.1",
- "mkdirp": "^1.0.3",
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -2104,12 +1562,6 @@
"node": ">= 0.8"
}
},
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "license": "MIT"
- },
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -2149,27 +1601,6 @@
"engines": {
"node": ">=18"
}
- },
- "node_modules/wide-align": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
- "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
- "license": "ISC",
- "dependencies": {
- "string-width": "^1.0.2 || 2 || 3 || 4"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "license": "ISC"
- },
- "node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "license": "ISC"
}
}
}
diff --git a/backend/package.json b/backend/package.json
index 6800df1b..bd01d79d 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -9,7 +9,7 @@
"dev": "nodemon server.js"
},
"dependencies": {
- "bcrypt": "^5.1.1",
+ "bcrypt": "^6.0.0",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
From 24a87af060f8aa69eff0ed6fd788a0284d6b9db1 Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Wed, 10 Jun 2026 11:06:08 +0200
Subject: [PATCH 32/40] =?UTF-8?q?Uppgraderade=20Vite=20f=C3=B6r=20att=20fi?=
=?UTF-8?q?xa=20dependabot=20security=20alarms?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
frontend/package-lock.json | 1730 +++++++++++++++---------------------
frontend/package.json | 6 +-
2 files changed, 743 insertions(+), 993 deletions(-)
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index e43d824e..9f2ec9cf 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -15,326 +15,229 @@
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
- "@vitejs/plugin-react": "^4.0.3",
+ "@vitejs/plugin-react": "^6.0.2",
"eslint": "^8.45.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
- "vite": "^4.4.5"
+ "vite": "^8.0.16"
}
},
- "node_modules/@babel/code-frame": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
- "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.28.5",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.1.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/compat-data": {
- "version": "7.29.3",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz",
- "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==",
- "dev": true,
+ "node_modules/@babel/runtime": {
+ "version": "7.29.2",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
+ "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@babel/core": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
- "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
+ "node_modules/@emnapi/core": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
+ "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
"dev": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
- "@babel/code-frame": "^7.29.0",
- "@babel/generator": "^7.29.0",
- "@babel/helper-compilation-targets": "^7.28.6",
- "@babel/helper-module-transforms": "^7.28.6",
- "@babel/helpers": "^7.28.6",
- "@babel/parser": "^7.29.0",
- "@babel/template": "^7.28.6",
- "@babel/traverse": "^7.29.0",
- "@babel/types": "^7.29.0",
- "@jridgewell/remapping": "^2.3.5",
- "convert-source-map": "^2.0.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.3",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
+ "@emnapi/wasi-threads": "1.2.1",
+ "tslib": "^2.4.0"
}
},
- "node_modules/@babel/generator": {
- "version": "7.29.1",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
- "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
+ "node_modules/@emnapi/runtime": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
+ "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
"dev": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
- "@babel/parser": "^7.29.0",
- "@babel/types": "^7.29.0",
- "@jridgewell/gen-mapping": "^0.3.12",
- "@jridgewell/trace-mapping": "^0.3.28",
- "jsesc": "^3.0.2"
- },
- "engines": {
- "node": ">=6.9.0"
+ "tslib": "^2.4.0"
}
},
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
- "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
+ "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
"dev": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
- "@babel/compat-data": "^7.28.6",
- "@babel/helper-validator-option": "^7.27.1",
- "browserslist": "^4.24.0",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
+ "tslib": "^2.4.0"
}
},
- "node_modules/@babel/helper-globals": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
- "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
- "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
+ "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.28.6",
- "@babel/types": "^7.28.6"
+ "eslint-visitor-keys": "^3.4.3"
},
"engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
- "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.28.6",
- "@babel/helper-validator-identifier": "^7.28.5",
- "@babel/traverse": "^7.28.6"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
- "engines": {
- "node": ">=6.9.0"
+ "funding": {
+ "url": "https://opencollective.com/eslint"
},
"peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-plugin-utils": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
- "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
}
},
- "node_modules/@babel/helper-string-parser": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
- "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=6.9.0"
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
},
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
- "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
"engines": {
- "node": ">=6.9.0"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
- "node_modules/@babel/helper-validator-option": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
- "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+ "node_modules/@eslint/js": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=6.9.0"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
- "node_modules/@babel/helpers": {
- "version": "7.29.2",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz",
- "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==",
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
+ "deprecated": "Use @eslint/config-array instead",
"dev": true,
- "license": "MIT",
+ "license": "Apache-2.0",
"dependencies": {
- "@babel/template": "^7.28.6",
- "@babel/types": "^7.29.0"
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
},
"engines": {
- "node": ">=6.9.0"
+ "node": ">=10.10.0"
}
},
- "node_modules/@babel/parser": {
- "version": "7.29.3",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz",
- "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==",
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.29.0"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
+ "license": "Apache-2.0",
"engines": {
- "node": ">=6.0.0"
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
}
},
- "node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
- "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
+ "license": "BSD-3-Clause"
},
- "node_modules/@babel/plugin-transform-react-jsx-source": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
- "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz",
+ "integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==",
"dev": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
+ "@tybys/wasm-util": "^0.10.2"
},
- "engines": {
- "node": ">=6.9.0"
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
},
"peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1"
}
},
- "node_modules/@babel/runtime": {
- "version": "7.29.2",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
- "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
- "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.28.6",
- "@babel/parser": "^7.28.6",
- "@babel/types": "^7.28.6"
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
},
"engines": {
- "node": ">=6.9.0"
+ "node": ">= 8"
}
},
- "node_modules/@babel/traverse": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
- "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.29.0",
- "@babel/generator": "^7.29.0",
- "@babel/helper-globals": "^7.28.0",
- "@babel/parser": "^7.29.0",
- "@babel/template": "^7.28.6",
- "@babel/types": "^7.29.0",
- "debug": "^4.3.1"
- },
"engines": {
- "node": ">=6.9.0"
+ "node": ">= 8"
}
},
- "node_modules/@babel/types": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
- "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5"
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
},
"engines": {
- "node": ">=6.9.0"
+ "node": ">= 8"
}
},
- "node_modules/@esbuild/android-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
- "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
- "cpu": [
- "arm"
- ],
+ "node_modules/@oxc-project/types": {
+ "version": "0.133.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz",
+ "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==",
"dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
}
},
- "node_modules/@esbuild/android-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
- "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz",
+ "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==",
"cpu": [
"arm64"
],
@@ -345,30 +248,13 @@
"android"
],
"engines": {
- "node": ">=12"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@esbuild/android-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
- "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
- "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+ "node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz",
+ "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==",
"cpu": [
"arm64"
],
@@ -379,13 +265,13 @@
"darwin"
],
"engines": {
- "node": ">=12"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
- "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz",
+ "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==",
"cpu": [
"x64"
],
@@ -396,30 +282,13 @@
"darwin"
],
"engines": {
- "node": ">=12"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
- "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
- "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz",
+ "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==",
"cpu": [
"x64"
],
@@ -430,503 +299,232 @@
"freebsd"
],
"engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
- "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
- "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
- "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
- "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
- "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
- "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
- "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
- "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
- "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
- "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
- "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
- "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
- "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
- "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
- "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@eslint-community/eslint-utils": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
- "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "eslint-visitor-keys": "^3.4.3"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- },
- "peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
- }
- },
- "node_modules/@eslint-community/regexpp": {
- "version": "4.12.2",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
- "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
- }
- },
- "node_modules/@eslint/eslintrc": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
- "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^9.6.0",
- "globals": "^13.19.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "minimatch": "^3.1.2",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint/js": {
- "version": "8.57.1",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
- "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/@humanwhocodes/config-array": {
- "version": "0.13.0",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
- "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
- "deprecated": "Use @eslint/config-array instead",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@humanwhocodes/object-schema": "^2.0.3",
- "debug": "^4.3.1",
- "minimatch": "^3.0.5"
- },
- "engines": {
- "node": ">=10.10.0"
- }
- },
- "node_modules/@humanwhocodes/module-importer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
- "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=12.22"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@humanwhocodes/object-schema": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
- "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
- "deprecated": "Use @eslint/object-schema instead",
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz",
+ "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
- "license": "BSD-3-Clause"
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.13",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz",
+ "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@jridgewell/remapping": {
- "version": "2.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
- "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz",
+ "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
+ "libc": [
+ "musl"
+ ],
"license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz",
+ "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==",
+ "cpu": [
+ "ppc64"
+ ],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=6.0.0"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz",
+ "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==",
+ "cpu": [
+ "s390x"
+ ],
"dev": true,
- "license": "MIT"
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz",
+ "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz",
+ "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
+ "libc": [
+ "musl"
+ ],
"license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">= 8"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz",
+ "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
"engines": {
- "node": ">= 8"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz",
+ "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==",
+ "cpu": [
+ "wasm32"
+ ],
"dev": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
+ "@emnapi/core": "1.10.0",
+ "@emnapi/runtime": "1.10.0",
+ "@napi-rs/wasm-runtime": "^1.1.4"
},
"engines": {
- "node": ">= 8"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-beta.27",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
- "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/babel__core": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
- "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz",
+ "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
"license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7",
- "@types/babel__generator": "*",
- "@types/babel__template": "*",
- "@types/babel__traverse": "*"
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@types/babel__generator": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
- "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz",
+ "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
"license": "MIT",
- "dependencies": {
- "@babel/types": "^7.0.0"
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@types/babel__template": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
- "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
+ "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0"
- }
+ "license": "MIT"
},
- "node_modules/@types/babel__traverse": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
- "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.2",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz",
+ "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==",
"dev": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
- "@babel/types": "^7.28.2"
+ "tslib": "^2.4.0"
}
},
"node_modules/@types/prop-types": {
@@ -965,24 +563,29 @@
"license": "ISC"
},
"node_modules/@vitejs/plugin-react": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
- "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.2.tgz",
+ "integrity": "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/core": "^7.28.0",
- "@babel/plugin-transform-react-jsx-self": "^7.27.1",
- "@babel/plugin-transform-react-jsx-source": "^7.27.1",
- "@rolldown/pluginutils": "1.0.0-beta.27",
- "@types/babel__core": "^7.20.5",
- "react-refresh": "^0.17.0"
+ "@rolldown/pluginutils": "^1.0.0"
},
"engines": {
- "node": "^14.18.0 || >=16.0.0"
+ "node": "^20.19.0 || >=22.12.0"
},
"peerDependencies": {
- "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
+ "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0",
+ "babel-plugin-react-compiler": "^1.0.0",
+ "vite": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@rolldown/plugin-babel": {
+ "optional": true
+ },
+ "babel-plugin-react-compiler": {
+ "optional": true
+ }
}
},
"node_modules/acorn": {
@@ -1229,19 +832,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/baseline-browser-mapping": {
- "version": "2.10.31",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.31.tgz",
- "integrity": "sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "baseline-browser-mapping": "dist/cli.cjs"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
"node_modules/brace-expansion": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz",
@@ -1253,40 +843,6 @@
"concat-map": "0.0.1"
}
},
- "node_modules/browserslist": {
- "version": "4.28.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
- "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "baseline-browser-mapping": "^2.10.12",
- "caniuse-lite": "^1.0.30001782",
- "electron-to-chromium": "^1.5.328",
- "node-releases": "^2.0.36",
- "update-browserslist-db": "^1.2.3"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
"node_modules/call-bind": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz",
@@ -1347,27 +903,6 @@
"node": ">=6"
}
},
- "node_modules/caniuse-lite": {
- "version": "1.0.30001793",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz",
- "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "CC-BY-4.0"
- },
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -1412,13 +947,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -1572,6 +1100,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@@ -1600,13 +1138,6 @@
"node": ">= 0.4"
}
},
- "node_modules/electron-to-chromium": {
- "version": "1.5.359",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.359.tgz",
- "integrity": "sha512-8lPELWuYZIWk7NDvCNthtmMw/7Q5Wu25NpM4djFMHBmk8DubPAtL4YTOp7ou0e7HyJtwkVlWv8XMLURnrtgJQw==",
- "dev": true,
- "license": "ISC"
- },
"node_modules/es-abstract": {
"version": "1.24.2",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz",
@@ -1784,54 +1315,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/esbuild": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
- "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=12"
- },
- "optionalDependencies": {
- "@esbuild/android-arm": "0.18.20",
- "@esbuild/android-arm64": "0.18.20",
- "@esbuild/android-x64": "0.18.20",
- "@esbuild/darwin-arm64": "0.18.20",
- "@esbuild/darwin-x64": "0.18.20",
- "@esbuild/freebsd-arm64": "0.18.20",
- "@esbuild/freebsd-x64": "0.18.20",
- "@esbuild/linux-arm": "0.18.20",
- "@esbuild/linux-arm64": "0.18.20",
- "@esbuild/linux-ia32": "0.18.20",
- "@esbuild/linux-loong64": "0.18.20",
- "@esbuild/linux-mips64el": "0.18.20",
- "@esbuild/linux-ppc64": "0.18.20",
- "@esbuild/linux-riscv64": "0.18.20",
- "@esbuild/linux-s390x": "0.18.20",
- "@esbuild/linux-x64": "0.18.20",
- "@esbuild/netbsd-x64": "0.18.20",
- "@esbuild/openbsd-x64": "0.18.20",
- "@esbuild/sunos-x64": "0.18.20",
- "@esbuild/win32-arm64": "0.18.20",
- "@esbuild/win32-ia32": "0.18.20",
- "@esbuild/win32-x64": "0.18.20"
- }
- },
- "node_modules/escalade": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
@@ -2096,6 +1579,24 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -2237,16 +1738,6 @@
"node": ">= 0.4"
}
},
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
@@ -2993,24 +2484,11 @@
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
+ "dependencies": {
+ "argparse": "^2.0.1"
},
- "engines": {
- "node": ">=6"
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
}
},
"node_modules/json-buffer": {
@@ -3034,19 +2512,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/jsx-ast-utils": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
@@ -3087,6 +2552,279 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/lightningcss": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
+ "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-android-arm64": "1.32.0",
+ "lightningcss-darwin-arm64": "1.32.0",
+ "lightningcss-darwin-x64": "1.32.0",
+ "lightningcss-freebsd-x64": "1.32.0",
+ "lightningcss-linux-arm-gnueabihf": "1.32.0",
+ "lightningcss-linux-arm64-gnu": "1.32.0",
+ "lightningcss-linux-arm64-musl": "1.32.0",
+ "lightningcss-linux-x64-gnu": "1.32.0",
+ "lightningcss-linux-x64-musl": "1.32.0",
+ "lightningcss-win32-arm64-msvc": "1.32.0",
+ "lightningcss-win32-x64-msvc": "1.32.0"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
+ "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
+ "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
+ "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
+ "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
+ "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
+ "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
+ "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
+ "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
+ "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
+ "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
+ "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -3122,16 +2860,6 @@
"loose-envify": "cli.js"
}
},
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -3207,13 +2935,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/node-releases": {
- "version": "2.0.44",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.44.tgz",
- "integrity": "sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -3457,6 +3178,19 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/possible-typed-array-names": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
@@ -3581,16 +3315,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/react-refresh": {
- "version": "0.17.0",
- "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
- "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/reflect.getprototypeof": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
@@ -3697,21 +3421,38 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/rollup": {
- "version": "3.30.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.30.0.tgz",
- "integrity": "sha512-kQvGasUgN+AlWGliFn2POSajRQEsULVYFGTvOZmK06d7vCD+YhZztt70kGk3qaeAXeWYL5eO7zx+rAubBc55eA==",
+ "node_modules/rolldown": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz",
+ "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@oxc-project/types": "=0.133.0",
+ "@rolldown/pluginutils": "^1.0.0"
+ },
"bin": {
- "rollup": "dist/bin/rollup"
+ "rolldown": "bin/cli.mjs"
},
"engines": {
- "node": ">=14.18.0",
- "npm": ">=8.0.0"
+ "node": "^20.19.0 || >=22.12.0"
},
"optionalDependencies": {
- "fsevents": "~2.3.2"
+ "@rolldown/binding-android-arm64": "1.0.3",
+ "@rolldown/binding-darwin-arm64": "1.0.3",
+ "@rolldown/binding-darwin-x64": "1.0.3",
+ "@rolldown/binding-freebsd-x64": "1.0.3",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.0.3",
+ "@rolldown/binding-linux-arm64-gnu": "1.0.3",
+ "@rolldown/binding-linux-arm64-musl": "1.0.3",
+ "@rolldown/binding-linux-ppc64-gnu": "1.0.3",
+ "@rolldown/binding-linux-s390x-gnu": "1.0.3",
+ "@rolldown/binding-linux-x64-gnu": "1.0.3",
+ "@rolldown/binding-linux-x64-musl": "1.0.3",
+ "@rolldown/binding-openharmony-arm64": "1.0.3",
+ "@rolldown/binding-wasm32-wasi": "1.0.3",
+ "@rolldown/binding-win32-arm64-msvc": "1.0.3",
+ "@rolldown/binding-win32-x64-msvc": "1.0.3"
}
},
"node_modules/run-parallel": {
@@ -4141,6 +3882,31 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/tinyglobby": {
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
+ "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "dev": true,
+ "license": "0BSD",
+ "optional": true
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -4264,37 +4030,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/update-browserslist-db": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
- "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "escalade": "^3.2.0",
- "picocolors": "^1.1.1"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
- }
- },
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -4306,50 +4041,66 @@
}
},
"node_modules/vite": {
- "version": "4.5.14",
- "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.14.tgz",
- "integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==",
+ "version": "8.0.16",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz",
+ "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "esbuild": "^0.18.10",
- "postcss": "^8.4.27",
- "rollup": "^3.27.1"
+ "lightningcss": "^1.32.0",
+ "picomatch": "^4.0.4",
+ "postcss": "^8.5.15",
+ "rolldown": "1.0.3",
+ "tinyglobby": "^0.2.17"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
- "node": "^14.18.0 || >=16.0.0"
+ "node": "^20.19.0 || >=22.12.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
},
"optionalDependencies": {
- "fsevents": "~2.3.2"
+ "fsevents": "~2.3.3"
},
"peerDependencies": {
- "@types/node": ">= 14",
- "less": "*",
- "lightningcss": "^1.21.0",
- "sass": "*",
- "stylus": "*",
- "sugarss": "*",
- "terser": "^5.4.0"
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "@vitejs/devtools": "^0.1.18",
+ "esbuild": "^0.27.0 || ^0.28.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
- "less": {
+ "@vitejs/devtools": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "jiti": {
"optional": true
},
- "lightningcss": {
+ "less": {
"optional": true
},
"sass": {
"optional": true
},
+ "sass-embedded": {
+ "optional": true
+ },
"stylus": {
"optional": true
},
@@ -4358,6 +4109,12 @@
},
"terser": {
"optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
}
}
},
@@ -4483,13 +4240,6 @@
"dev": true,
"license": "ISC"
},
- "node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true,
- "license": "ISC"
- },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index fc417bb3..c770be32 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -17,11 +17,11 @@
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
- "@vitejs/plugin-react": "^4.0.3",
+ "@vitejs/plugin-react": "^6.0.2",
"eslint": "^8.45.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
- "vite": "^4.4.5"
+ "vite": "^8.0.16"
}
-}
\ No newline at end of file
+}
From 2466c96bd1d9fbd8a0567ef33f47973325154ffb Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Wed, 10 Jun 2026 11:22:44 +0200
Subject: [PATCH 33/40] Run npm audit fix to resolve qs vulnerability
---
backend/package-lock.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/backend/package-lock.json b/backend/package-lock.json
index 35834289..8ae74d1b 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -1233,9 +1233,9 @@
}
},
"node_modules/qs": {
- "version": "6.15.1",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz",
- "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==",
+ "version": "6.15.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
+ "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
From 918b4786d7ca1af1fc055660a23cf204312c26d3 Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Thu, 11 Jun 2026 13:40:24 +0200
Subject: [PATCH 34/40] Specificerade JWT-algoritmen
---
backend/middleware/auth.js | 2 +-
backend/server.js | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/backend/middleware/auth.js b/backend/middleware/auth.js
index e3bdf47c..b0c422fb 100644
--- a/backend/middleware/auth.js
+++ b/backend/middleware/auth.js
@@ -7,7 +7,7 @@ export const authenticateUser = async (req, res, next) => {
return res.status(401).json({ success: false, message: "No token provided" })
}
try {
- const decoded = jwt.verify(token, process.env.JWT_SECRET)
+ const decoded = jwt.verify(token, process.env.JWT_SECRET, { algorithms: ["HS256"] }) //fas 3: Låser verifieringen till algoritmen HS256 så att tokens inte kan godkännas med "none"-algoritm eller annan algoritm.
const user = await User.findById(decoded.userId)
if (!user) {
return res.status(401).json({ success: false, message: "User not found" })
diff --git a/backend/server.js b/backend/server.js
index e9bd4d34..7f24d970 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -58,10 +58,11 @@ app.post("/register", async (req, res) => {
const user = new User({ username: username.trim(), email, password: hashedPassword })
await user.save()
+ /// Anger algoritmen explicit så signering och verifiering inte kan glida isär ifall default-algoritmen i JWT-biblioteket ändras.
const accessToken = jwt.sign(
{ userId: user._id, username: user.username },
process.env.JWT_SECRET,
- { expiresIn: "2h" }
+ { expiresIn: "2h", algorithm: "HS256" }
)
res.status(201).json({
From 38b4234b0d6eea232f0deac4d11b0811c7fe40cc Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Thu, 11 Jun 2026 19:05:16 +0200
Subject: [PATCH 35/40] granskningsfasen
---
backend/server.js | 4 ++--
frontend/src/App.jsx | 2 +-
granskningsfasen.md | 40 +++++++++++++++++++++++++++++++++++++++-
3 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/backend/server.js b/backend/server.js
index 7f24d970..28e6c5a1 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -108,11 +108,11 @@ app.post("/login", loginLimiter, async (req, res) => {
response: null,
})
}
-
+ /// fas 3: Anger algoritmen explicit så signering och verifiering inte kan glida isär ifall default-algoritmen i JWT-biblioteket ändras.
const accessToken = jwt.sign(
{ userId: user._id, username: user.username },
process.env.JWT_SECRET,
- { expiresIn: "2h" }
+ { expiresIn: "2h", algorithm: "HS256" }
)
res.json({
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 011e67c7..f58bccf3 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -11,7 +11,7 @@ export const App = () => {
const [modal, setModal] = useState(null)
const [error, setError] = useState(null)
- //Säkerhetskrav 3: Nedan är ny fetchPosts variabel. När vi la till authenticateUser på GET /messages i backenden som en del av säkerhetskrav 3, att endast inloggade ska kunna se meddelanden, behövde frontenden också skicka med JWT-token i varje anrop, annars svarar backenden med 401 och inga meddelanden visas. Funktionen hämtar nu meddelanden från backenden och skickar med en Authorization-header som innehåller användarens JWT-token. Backenden använder token för att verifiera att användaren är inloggad innan den returnerar meddelandena. Utan token blockeras anropet av authenticateUser-middleware och inga meddelanden skickas tillbaka.
+ //Säkerhetskrav 3: Nedan är ny fetchPosts-funktion. När vi la till authenticateUser på GET /messages i backenden som en del av säkerhetskrav 3, att endast inloggade ska kunna se meddelanden, behövde frontenden också skicka med JWT-token i varje anrop, annars svarar backenden med 401 och inga meddelanden visas. Funktionen hämtar nu meddelanden från backenden och skickar med en Authorization-header som innehåller användarens JWT-token. Backenden använder token för att verifiera att användaren är inloggad innan den returnerar meddelandena. Utan token blockeras anropet av authenticateUser-middleware och inga meddelanden skickas tillbaka.
const fetchPosts = () => {
setLoading(true)
fetch(`${BASE_URL}/messages`, {
diff --git a/granskningsfasen.md b/granskningsfasen.md
index 088f9718..a1a421d6 100644
--- a/granskningsfasen.md
+++ b/granskningsfasen.md
@@ -1 +1,39 @@
-# Inlämning 3 - Granskningsfasen
\ No newline at end of file
+# Inlämning 3 - Granskningsfasen
+
+Jag använde mig av CodeQL och Dependabot i GitHub för att granska koden.
+
+## CodeQL larmade om 9 problem i koden
+
+**CORS-konfiguration** 1 av CodeQL-larmen var CORS-sårbarheten som jag redan hittat själv i fas 2. Att CORS-konfigurationen var för slapp mappar jag mot OWASP 2025 A02: Security Misconfiguration. Det är åtgärdat genom att jag ändrade origin från "*" till "http://localhost:5173". I en deployad version skulle det ändras till min frontend-URL.
+
+**Rate limiting** 8 av 9 larm i CodeQL. Utan rate limiting på endpointsen kan en angripare skicka tusentals requests per sekund till API:et, vilket överlastar servern och gör tjänsten otillgänglig för riktiga användare (DoS). Detta mappar jag mot OWASP 2025: A04: Insecure Design.
+
+För att åtgärda detta skapade jag en ny middleware i rateLimiter.js, som jag döpte till generalLimiter som tillåter som mest 100 requests per IP under 15 minuter.
+
+Först satte jag den per endpoint, men larm kvarstod eftersom jag placerat den efter authenticateUser i middleware-ordningen. Ett databasanrop hann alltså ske innan limitern stoppade requesten. Jag la den därför globalt i stället. Det följer principen secure by default då alla endpoints, även nya, skyddas automatiskt utan att utvecklaren behöver komma ihåg att lägga till limitern per endpoint. Det följer också DRY-principen, eftersom skyddet definieras på ett ställe i stället för att upprepas.
+
+## Dependabot
+Dependabot larmade om 16 potentiella sårbarheter som jag löste genom att uppdatera de olika biblioteken som var berörda. Övergripande mappar sårbarheterna mot OWASP 2025 A03: Software Supply Chain Failures som handlar om risker i kedjan av kod man förlitar sig på.
+
+**jsonwebtoken (3 larm).** Version 8.5.1 hade brister i hur tokens verifieras, varav en av de tre bristerna kunde ha en påverkan på vår app genom koden.
+Den gamla versionen av biblioteket kunde under vissa förhållanden luras att godkänna en token som inte hade en signatur. För att kryphålet skulle kunna utnyttjas krävdes tre saker samtidigt: att ingen algoritm angavs i jwt.verify(), att en token utan signatur togs emot, och att JWT_SECRET var falsy (saknades eller laddades inte). Var alla tre uppfyllda kunde verifieringen falla tillbaka på algoritmen "none" och godkänna en oäkta token. I vår app var ingen algoritm angiven, och eftersom en angripare alltid kan skicka en signaturlös token, så hölls skyddet uppe bara av att JWT_SECRET var korrekt ifylld. Hade den saknats eller laddats fel hade kryphålet öppnats.
+
+De två övriga jwt-larmen rörde verifiering med asymmetriska nycklar och var inte aktuella för vår webapp.
+Lösningen för alla tre larmen var att uppgradera till 9.0.0, där algoritmen "none" inte längre finns att falla tillbaka på.
+
+**tar (6 larm).** tar är ett uppackningsverktyg som låg flera led ner bland beroendena. Hashningsbiblioteket bcrypt använde ett verktyg som i sin tur använde tar för att packa upp filer vid installation. tar kontrollerade inte vart filerna i ett paket tog vägen, så ett illvilligt paket hade kunnat lägga skadliga filer på fel ställen på utvecklarens dator, och i värsta fall köra skadlig kod där. Dependabot kunde inte lösa larmen automatiskt, eftersom den lagade versionen av tar var nyare än vad mellanledet tillät, och Dependabot får inte bryta ett pakets versionskrav på egen hand. Jag löste det genom att uppgradera bcrypt till en version som inte längre använder tar.
+
+**Vite/esbuild – obehörig åtkomst till utvecklingsservern (5 larm).** Vites utvecklingsserver serverar projektets filer till webbläsaren och har regler för vad som inte får lämnas ut (t.ex. .env med hemligheter). Fem larm var olika sätt den kontrollen kunde kringgås. Gemensamt: data som borde varit skyddad kunde läsas av obehöriga. Vite körs bara under utveckling och följer inte med i den färdiga appen, så risken för användarna var låg, men det är viktigt att hemligheter i .env inte sprids.
+
+**launch-editor – kommandoinjektion (1 larm).** Vite har en funktion där man kan klicka på ett felmeddelande i webbläsaren för att öppna rätt fil i sin kodeditor, vilket sköts av verktyget launch-editor som kör ett kommando på datorn. På Windows kunde en manipulerad förfrågan injicera egna kommandon i det anropet, alltså få datorn att köra angriparens kod.
+
+Samtliga Vite-kopplade larm åtgärdades genom att jag uppgraderade Vite från v4 till v8.
+
+**qs (1 larm).** qs är ett paket som följer med Express och hanterar query-strängar. Dependabot larmade om att en bugg i funktionen qs.stringify under specifika inställningar kunde få servern att krascha (DoS). När jag granskade min kod såg jag dock att jag aldrig använder den sårbara kodvägen, så buggen var i praktiken inte exploaterbar hos vår app. Jag åtgärdade larmet ändå med npm audit fix, eftersom paketet körs i drift och den lagade versionen rymdes inom tillåtet versionsspann.
+
+## Sammanfattning dependabot
+Efter att ha granskat min kod kan jag konstatera som koden ser ut nu var varken qs eller jsonwebtoken-sårbarheterna exploaterbara i praktiken: jag använder aldrig den sårbara qs-funktionen (qs.stringify med encodeValuesOnly), och jwt-kryphålet hölls stängt av att JWT_SECRET var satt. Larmen var alltså reella, men den faktiska risken för min app var låg.
+
+Samma relativt låga risk gäller även de övriga larmen. tar kördes bara vid installation, inte av min kod, och kunde bara utnyttjas om någon lyckades mata in ett manipulerat arkiv i nedladdningssteget, låg sannolikhet, men hög konsekvens (kodkörning på utvecklarens dator), vilket motiverade åtgärd. Två av Vite-larmen var Windows-specifika och därför inte aktuella på min Mac, medan de återstående Vite- och esbuild-larmen krävde att utvecklingsservern var igång och kunde nås av manipulerade förfrågningar, i praktiken genom att jag besökte en illvillig webbsida medan servern kördes. Det är en smal attackväg som bara var relevant under aktiv utveckling, inte i den färdiga appen.
+
+Samtliga dependabot-larm var reella, men den praktiska risken för att sårbarheterna skulle exploateras var låg, antingen på grund av att jag inte anropade sårbar kod (qs, jwt), att sårbarheten gällde annat operativsystem än mitt (Vite på Windows), samt smal attackväg genom installations- och utvecklingsmiljön (tar, esbuild) Att avgöra det krävde att jag gick från vad verktyget rapporterade till vad det faktiskt betydde för min kodbas och miljö.
From 28a69e78b6ad999d9cc45c59a1c33db7b2d25740 Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Thu, 11 Jun 2026 22:49:44 +0200
Subject: [PATCH 36/40] granskningsfasen
---
granskningsfasen.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/granskningsfasen.md b/granskningsfasen.md
index a1a421d6..f48e81a2 100644
--- a/granskningsfasen.md
+++ b/granskningsfasen.md
@@ -6,7 +6,7 @@ Jag använde mig av CodeQL och Dependabot i GitHub för att granska koden.
**CORS-konfiguration** 1 av CodeQL-larmen var CORS-sårbarheten som jag redan hittat själv i fas 2. Att CORS-konfigurationen var för slapp mappar jag mot OWASP 2025 A02: Security Misconfiguration. Det är åtgärdat genom att jag ändrade origin från "*" till "http://localhost:5173". I en deployad version skulle det ändras till min frontend-URL.
-**Rate limiting** 8 av 9 larm i CodeQL. Utan rate limiting på endpointsen kan en angripare skicka tusentals requests per sekund till API:et, vilket överlastar servern och gör tjänsten otillgänglig för riktiga användare (DoS). Detta mappar jag mot OWASP 2025: A04: Insecure Design.
+**Rate limiting** 8 av 9 larm i CodeQL. Utan rate limiting på endpointsen kan en angripare skicka tusentals requests per sekund till API:et, vilket överlastar servern och gör tjänsten otillgänglig för riktiga användare (DoS). Detta mappar jag mot OWASP 2025: A06: Insecure Design.
För att åtgärda detta skapade jag en ny middleware i rateLimiter.js, som jag döpte till generalLimiter som tillåter som mest 100 requests per IP under 15 minuter.
From 438d6371e5bba1a93fa52c88a19f979c79c9cb3e Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Thu, 11 Jun 2026 22:49:56 +0200
Subject: [PATCH 37/40] granskningsfasen
---
backend/middleware/rateLimiter.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/middleware/rateLimiter.js b/backend/middleware/rateLimiter.js
index 3b786bd4..816d5aa4 100644
--- a/backend/middleware/rateLimiter.js
+++ b/backend/middleware/rateLimiter.js
@@ -9,7 +9,7 @@ export const loginLimiter = rateLimit({
// Säkerhetskrav 6. Här har jag lagt in en funktion loginLimiter som använder express-rate-limit för att begränsa antalet inloggningsförsök till 5 per 15 minuter. Sedan använder jag loginLimiter som middleware i server.js: app.post("/login") för att tillämpa denna begränsning på inloggningsförsöken.
-// Efter att ha använt CodeQL och hittat sårbarheter la jag till ytterligare en limiter för att använda på övriga endpoints som gör databasanrop. Annars kan en angripare skicka tusentals requests per sekund och överlasta databas/server. Satte ett högre tak än loginLimiter eftersom 5 anrop på 15 minuter skulle göra appen oanvändbar på tex /messages GET/POST/PATCH/DELETE.
+// fas 3: Efter att ha använt CodeQL och hittat sårbarheter la jag till ytterligare en limiter för att använda på övriga endpoints som gör databasanrop. Annars kan en angripare skicka tusentals requests per sekund och överlasta databas/server. Satte ett högre tak än loginLimiter eftersom 5 anrop på 15 minuter skulle göra appen oanvändbar på tex /messages GET/POST/PATCH/DELETE.
export const generalLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minuter
max: 100, // 100 requests per 15 min per IP
From 46466f82d57741371f4b26da658273be4e2b6cb0 Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Thu, 11 Jun 2026 22:54:47 +0200
Subject: [PATCH 38/40] granskningsfasen
---
granskningsfasen.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/granskningsfasen.md b/granskningsfasen.md
index f48e81a2..e2022f75 100644
--- a/granskningsfasen.md
+++ b/granskningsfasen.md
@@ -16,7 +16,7 @@ Först satte jag den per endpoint, men larm kvarstod eftersom jag placerat den e
Dependabot larmade om 16 potentiella sårbarheter som jag löste genom att uppdatera de olika biblioteken som var berörda. Övergripande mappar sårbarheterna mot OWASP 2025 A03: Software Supply Chain Failures som handlar om risker i kedjan av kod man förlitar sig på.
**jsonwebtoken (3 larm).** Version 8.5.1 hade brister i hur tokens verifieras, varav en av de tre bristerna kunde ha en påverkan på vår app genom koden.
-Den gamla versionen av biblioteket kunde under vissa förhållanden luras att godkänna en token som inte hade en signatur. För att kryphålet skulle kunna utnyttjas krävdes tre saker samtidigt: att ingen algoritm angavs i jwt.verify(), att en token utan signatur togs emot, och att JWT_SECRET var falsy (saknades eller laddades inte). Var alla tre uppfyllda kunde verifieringen falla tillbaka på algoritmen "none" och godkänna en oäkta token. I vår app var ingen algoritm angiven, och eftersom en angripare alltid kan skicka en signaturlös token, så hölls skyddet uppe bara av att JWT_SECRET var korrekt ifylld. Hade den saknats eller laddats fel hade kryphålet öppnats.
+Den gamla versionen av biblioteket kunde under vissa förhållanden luras att godkänna en token som inte hade en signatur. För att kryphålet skulle kunna utnyttjas krävdes tre saker samtidigt: att ingen algoritm angavs i jwt.verify(), att en token utan signatur togs emot, och att JWT_SECRET var falsy (saknades eller laddades inte). Var alla tre uppfyllda kunde verifieringen falla tillbaka på algoritmen "none" och godkänna en oäkta token. I vår app var ingen algoritm angiven, och eftersom en angripare alltid kan skicka en signaturlös token, så hölls skyddet uppe bara av att JWT_SECRET var korrekt ifylld. Hade den saknats eller laddats fel hade kryphålet öppnats. Konsekvensen hade varit ett autentiseringshaveri, och kunnat mappas mot OWASP A07: Authentication Failures.
De två övriga jwt-larmen rörde verifiering med asymmetriska nycklar och var inte aktuella för vår webapp.
Lösningen för alla tre larmen var att uppgradera till 9.0.0, där algoritmen "none" inte längre finns att falla tillbaka på.
From bea045f7c04ef005057d173922d3a60fe735ae0a Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Thu, 11 Jun 2026 23:42:52 +0200
Subject: [PATCH 39/40] granskningsfasen
---
granskningsfasen.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/granskningsfasen.md b/granskningsfasen.md
index e2022f75..0257942f 100644
--- a/granskningsfasen.md
+++ b/granskningsfasen.md
@@ -32,8 +32,8 @@ Samtliga Vite-kopplade larm åtgärdades genom att jag uppgraderade Vite från v
**qs (1 larm).** qs är ett paket som följer med Express och hanterar query-strängar. Dependabot larmade om att en bugg i funktionen qs.stringify under specifika inställningar kunde få servern att krascha (DoS). När jag granskade min kod såg jag dock att jag aldrig använder den sårbara kodvägen, så buggen var i praktiken inte exploaterbar hos vår app. Jag åtgärdade larmet ändå med npm audit fix, eftersom paketet körs i drift och den lagade versionen rymdes inom tillåtet versionsspann.
## Sammanfattning dependabot
-Efter att ha granskat min kod kan jag konstatera som koden ser ut nu var varken qs eller jsonwebtoken-sårbarheterna exploaterbara i praktiken: jag använder aldrig den sårbara qs-funktionen (qs.stringify med encodeValuesOnly), och jwt-kryphålet hölls stängt av att JWT_SECRET var satt. Larmen var alltså reella, men den faktiska risken för min app var låg.
+Efter att ha granskat min kod kan jag konstatera att som koden ser ut nu var varken qs eller jsonwebtoken-sårbarheterna exploaterbara i praktiken: jag använder aldrig den sårbara qs-funktionen (qs.stringify med encodeValuesOnly), och jwt-kryphålet hölls stängt av att JWT_SECRET var satt. Larmen var alltså reella, men den faktiska risken för min app var låg.
-Samma relativt låga risk gäller även de övriga larmen. tar kördes bara vid installation, inte av min kod, och kunde bara utnyttjas om någon lyckades mata in ett manipulerat arkiv i nedladdningssteget, låg sannolikhet, men hög konsekvens (kodkörning på utvecklarens dator), vilket motiverade åtgärd. Två av Vite-larmen var Windows-specifika och därför inte aktuella på min Mac, medan de återstående Vite- och esbuild-larmen krävde att utvecklingsservern var igång och kunde nås av manipulerade förfrågningar, i praktiken genom att jag besökte en illvillig webbsida medan servern kördes. Det är en smal attackväg som bara var relevant under aktiv utveckling, inte i den färdiga appen.
+tar körs bara vid installation, inte av min kod, och kan bara utnyttjas om ett manipulerat arkiv matas in i nedladdningssteget. En riktad attack mot just min nedladdning är osannolik, men leveranskedjeattacker behöver inte vara riktade: om någon planterar skadlig kod i en populär källa drabbas alla som laddar ner därifrån, oavsett hur litet projektet är. Den sortens attack har hänt flera gånger i verkligheten, och konsekvensen hade varit allvarlig (kodkörning på utvecklarens dator), vilket motiverade åtgärd trots att mitt enskilda projekt är ett osannolikt mål.
-Samtliga dependabot-larm var reella, men den praktiska risken för att sårbarheterna skulle exploateras var låg, antingen på grund av att jag inte anropade sårbar kod (qs, jwt), att sårbarheten gällde annat operativsystem än mitt (Vite på Windows), samt smal attackväg genom installations- och utvecklingsmiljön (tar, esbuild) Att avgöra det krävde att jag gick från vad verktyget rapporterade till vad det faktiskt betydde för min kodbas och miljö.
+Två av Vite-larmen var Windows-specifika och därför inte aktuella på min Mac, medan de återstående Vite- och esbuild-larmen krävde att utvecklingsservern var igång och kunde nås av manipulerade förfrågningar, i praktiken genom att jag besöker en illvillig webbsida medan servern kördes. Det är en smal attackväg som bara är relevant under aktiv utveckling, inte i den färdiga appen.
\ No newline at end of file
From f619bb5720ba766710f8edad0933cb3bef5477e1 Mon Sep 17 00:00:00 2001
From: Karin Isaksson
Date: Fri, 12 Jun 2026 14:50:39 +0200
Subject: [PATCH 40/40] slutsats
---
granskningsfasen.md | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/granskningsfasen.md b/granskningsfasen.md
index 0257942f..d9ea8bfb 100644
--- a/granskningsfasen.md
+++ b/granskningsfasen.md
@@ -36,4 +36,8 @@ Efter att ha granskat min kod kan jag konstatera att som koden ser ut nu var var
tar körs bara vid installation, inte av min kod, och kan bara utnyttjas om ett manipulerat arkiv matas in i nedladdningssteget. En riktad attack mot just min nedladdning är osannolik, men leveranskedjeattacker behöver inte vara riktade: om någon planterar skadlig kod i en populär källa drabbas alla som laddar ner därifrån, oavsett hur litet projektet är. Den sortens attack har hänt flera gånger i verkligheten, och konsekvensen hade varit allvarlig (kodkörning på utvecklarens dator), vilket motiverade åtgärd trots att mitt enskilda projekt är ett osannolikt mål.
-Två av Vite-larmen var Windows-specifika och därför inte aktuella på min Mac, medan de återstående Vite- och esbuild-larmen krävde att utvecklingsservern var igång och kunde nås av manipulerade förfrågningar, i praktiken genom att jag besöker en illvillig webbsida medan servern kördes. Det är en smal attackväg som bara är relevant under aktiv utveckling, inte i den färdiga appen.
\ No newline at end of file
+Två av Vite-larmen var Windows-specifika och därför inte aktuella på min Mac, medan de återstående Vite- och esbuild-larmen krävde att utvecklingsservern var igång och kunde nås av manipulerade förfrågningar, i praktiken genom att jag besöker en illvillig webbsida medan servern kördes. Det är en smal attackväg som bara är relevant under aktiv utveckling, inte i den färdiga appen.
+
+## Slutsats
+
+Både CodeQL och Dependabot larmade om sårbarheter som jag inte hittat själv, vid manuell granskning (där jag tog hjälp av Claude Code). Det känns viktigt att kunna använda sådana verktyg, speciellt när utvecklingscommunityt är byggt på att man använder andras bibliotek. Det hade varit väldigt svårt att hålla koll på vilka sårbarheter man drar in annars. Jag löste alla dependabot-larmen, men var noga med att testa alla appens funktioner efter varje uppdatering för att inget skulle gå sönder.