feat: separate user and admin auth, redirect to settings after invite

This commit is contained in:
Isaac 2025-02-09 23:12:53 +00:00
parent 05c6ffa482
commit 2255d0d15d
No known key found for this signature in database
GPG Key ID: 0DE40AE37BBA5C33
8 changed files with 265 additions and 305 deletions

View File

@ -52,9 +52,9 @@
"@eartharoid/dbf": "^0.4.2", "@eartharoid/dbf": "^0.4.2",
"@eartharoid/dtf": "^2.0.1", "@eartharoid/dtf": "^2.0.1",
"@eartharoid/i18n": "^1.2.1", "@eartharoid/i18n": "^1.2.1",
"@fastify/cookie": "^9.4.0", "@fastify/cookie": "^11.0.2",
"@fastify/jwt": "^8.0.1", "@fastify/jwt": "^9.0.3",
"@fastify/oauth2": "^7.9.0", "@fastify/multipart": "^9.0.3",
"@prisma/client": "^4.16.2", "@prisma/client": "^4.16.2",
"archiver": "^7.0.1", "archiver": "^7.0.1",
"boxen": "^7.1.1", "boxen": "^7.1.1",
@ -62,7 +62,7 @@
"cryptr": "^6.3.0", "cryptr": "^6.3.0",
"discord.js": "^14.17.3", "discord.js": "^14.17.3",
"dotenv": "^16.4.7", "dotenv": "^16.4.7",
"fastify": "^4.29.0", "fastify": "^5.2.1",
"figlet": "^1.8.0", "figlet": "^1.8.0",
"fs-extra": "^10.1.0", "fs-extra": "^10.1.0",
"keyv": "^4.5.4", "keyv": "^4.5.4",
@ -80,6 +80,7 @@
"spacetime": "^7.7.0", "spacetime": "^7.7.0",
"terminal-link": "^2.1.1", "terminal-link": "^2.1.1",
"threads": "^1.7.0", "threads": "^1.7.0",
"unzipper": "^0.12.3",
"yaml": "^2.7.0" "yaml": "^2.7.0"
}, },
"devDependencies": { "devDependencies": {

386
pnpm-lock.yaml generated
View File

@ -21,14 +21,14 @@ importers:
specifier: ^1.2.1 specifier: ^1.2.1
version: 1.2.1 version: 1.2.1
'@fastify/cookie': '@fastify/cookie':
specifier: ^9.4.0 specifier: ^11.0.2
version: 9.4.0 version: 11.0.2
'@fastify/jwt': '@fastify/jwt':
specifier: ^8.0.1 specifier: ^9.0.3
version: 8.0.1 version: 9.0.3
'@fastify/oauth2': '@fastify/multipart':
specifier: ^7.9.0 specifier: ^9.0.3
version: 7.9.0 version: 9.0.3
'@prisma/client': '@prisma/client':
specifier: ^4.16.2 specifier: ^4.16.2
version: 4.16.2(prisma@4.16.2) version: 4.16.2(prisma@4.16.2)
@ -51,8 +51,8 @@ importers:
specifier: ^16.4.7 specifier: ^16.4.7
version: 16.4.7 version: 16.4.7
fastify: fastify:
specifier: ^4.29.0 specifier: ^5.2.1
version: 4.29.0 version: 5.2.1
figlet: figlet:
specifier: ^1.8.0 specifier: ^1.8.0
version: 1.8.0 version: 1.8.0
@ -104,6 +104,9 @@ importers:
threads: threads:
specifier: ^1.7.0 specifier: ^1.7.0
version: 1.7.0 version: 1.7.0
unzipper:
specifier: ^0.12.3
version: 0.12.3
yaml: yaml:
specifier: ^2.7.0 specifier: ^2.7.0
version: 2.7.0 version: 2.7.0
@ -300,44 +303,38 @@ packages:
resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
'@fastify/ajv-compiler@3.6.0': '@fastify/ajv-compiler@4.0.2':
resolution: {integrity: sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==} resolution: {integrity: sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==}
'@fastify/cookie@9.4.0': '@fastify/busboy@3.1.1':
resolution: {integrity: sha512-Th+pt3kEkh4MQD/Q2q1bMuJIB5NX/D5SwSpOKu3G/tjoGbwfpurIMJsWSPS0SJJ4eyjtmQ8OipDQspf8RbUOlg==} resolution: {integrity: sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==}
'@fastify/error@3.4.1': '@fastify/cookie@11.0.2':
resolution: {integrity: sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==} resolution: {integrity: sha512-GWdwdGlgJxyvNv+QcKiGNevSspMQXncjMZ1J8IvuDQk0jvkzgWWZFNC2En3s+nHndZBGV8IbLwOI/sxCZw/mzA==}
'@fastify/fast-json-stringify-compiler@4.3.0': '@fastify/deepmerge@2.0.2':
resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} resolution: {integrity: sha512-3wuLdX5iiiYeZWP6bQrjqhrcvBIf0NHbQH1Ur1WbHvoiuTYUEItgygea3zs8aHpiitn0lOB8gX20u1qO+FDm7Q==}
'@fastify/jwt@8.0.1': '@fastify/error@4.0.0':
resolution: {integrity: sha512-295bd7V6bDCnZOu8MAQgM6r7V1KILB+kdEq1q6nbHfXCnML569n7NSo3WzeLDG6IAqDl+Rhzi1vjxwaNHhRCBA==} resolution: {integrity: sha512-OO/SA8As24JtT1usTUTKgGH7uLvhfwZPwlptRi2Dp5P4KKmJI3gvsZ8MIHnNwDs4sLf/aai5LzTyl66xr7qMxA==}
'@fastify/merge-json-schemas@0.1.1': '@fastify/fast-json-stringify-compiler@5.0.2':
resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==} resolution: {integrity: sha512-YdR7gqlLg1xZAQa+SX4sMNzQHY5pC54fu9oC5aYSUqBhyn6fkLkrdtKlpVdCNPlwuUuXA1PjFTEmvMF6ZVXVGw==}
'@fastify/oauth2@7.9.0': '@fastify/forwarded@3.0.0':
resolution: {integrity: sha512-OsMr+M2FI7ib/UKZ8hC4SRnUBQqgJ0EsvAhn1qrdYJ9K/U5OwaM2sQM8fLEYbKYQRlH0oxC7lvdTm8Ncd5+ukA==} resolution: {integrity: sha512-kJExsp4JCms7ipzg7SJ3y8DwmePaELHxKYtg+tZow+k0znUTf3cb+npgyqm8+ATZOdmfgfydIebPDWM172wfyA==}
'@hapi/boom@10.0.1': '@fastify/jwt@9.0.3':
resolution: {integrity: sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA==} resolution: {integrity: sha512-5OjeozLzwhMhrOkadHG9FhS5S3wNVIN6ADhBJd/x3VJIWptlRdc1ORksA6NHJ1ihvuAb0IOVK9giaCZTelnMSg==}
'@hapi/bourne@3.0.0': '@fastify/merge-json-schemas@0.2.1':
resolution: {integrity: sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==} resolution: {integrity: sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==}
'@hapi/hoek@11.0.7': '@fastify/multipart@9.0.3':
resolution: {integrity: sha512-HV5undWkKzcB4RZUusqOpcgxOaq6VOAH7zhhIr2g3G8NF/MlFO75SjOr2NfuSx0Mh40+1FqCkagKLJRykUWoFQ==} resolution: {integrity: sha512-pJogxQCrT12/6I5Fh6jr3narwcymA0pv4B0jbC7c6Bl9wnrxomEUnV0d26w6gUls7gSXmhG8JGRMmHFIPsxt1g==}
'@hapi/hoek@9.3.0': '@fastify/proxy-addr@5.0.0':
resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} resolution: {integrity: sha512-37qVVA1qZ5sgH7KpHkkC4z9SK6StIsIcOmpjvMPXNb3vx2GQxhZocogVYbr2PbbeLCQxYIPDok307xEvRZOzGA==}
'@hapi/topo@5.1.0':
resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==}
'@hapi/wreck@18.1.0':
resolution: {integrity: sha512-0z6ZRCmFEfV/MQqkQomJ7sl/hyxvcZM7LtuVqN3vdAO4vM9eBbowl0kaqQj9EJJQab+3Uuh1GxbGIBFy4NfJ4w==}
'@humanwhocodes/config-array@0.13.0': '@humanwhocodes/config-array@0.13.0':
resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==}
@ -417,15 +414,6 @@ packages:
resolution: {integrity: sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==} resolution: {integrity: sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==}
engines: {node: '>=v14.0.0', npm: '>=7.0.0'} engines: {node: '>=v14.0.0', npm: '>=7.0.0'}
'@sideway/address@4.1.5':
resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==}
'@sideway/formula@3.0.1':
resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==}
'@sideway/pinpoint@2.0.0':
resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==}
'@tsconfig/node10@1.0.11': '@tsconfig/node10@1.0.11':
resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==}
@ -488,14 +476,6 @@ packages:
add-stream@1.0.0: add-stream@1.0.0:
resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==} resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==}
ajv-formats@2.1.1:
resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
peerDependencies:
ajv: ^8.0.0
peerDependenciesMeta:
ajv:
optional: true
ajv-formats@3.0.1: ajv-formats@3.0.1:
resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
peerDependencies: peerDependencies:
@ -577,8 +557,8 @@ packages:
resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
engines: {node: '>=8.0.0'} engines: {node: '>=8.0.0'}
avvio@8.4.0: avvio@9.1.0:
resolution: {integrity: sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==} resolution: {integrity: sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==}
b4a@1.6.7: b4a@1.6.7:
resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==}
@ -599,6 +579,9 @@ packages:
bindings@1.5.0: bindings@1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
bluebird@3.7.2:
resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
bn.js@4.12.1: bn.js@4.12.1:
resolution: {integrity: sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==} resolution: {integrity: sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==}
@ -808,13 +791,9 @@ packages:
engines: {node: '>=14'} engines: {node: '>=14'}
hasBin: true hasBin: true
cookie-signature@1.2.2: cookie@1.0.2:
resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
engines: {node: '>=6.6.0'} engines: {node: '>=18'}
cookie@0.7.2:
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
engines: {node: '>= 0.6'}
core-util-is@1.0.3: core-util-is@1.0.3:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
@ -900,6 +879,10 @@ packages:
deep-is@0.1.4: deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dequal@2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
didyoumean@1.2.2: didyoumean@1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
@ -926,6 +909,9 @@ packages:
resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
duplexer2@0.1.4:
resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==}
eastasianwidth@0.2.0: eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
@ -1035,9 +1021,6 @@ packages:
resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
engines: {node: '>=4'} engines: {node: '>=4'}
fast-content-type-parse@1.1.0:
resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==}
fast-decode-uri-component@1.0.1: fast-decode-uri-component@1.0.1:
resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==}
@ -1050,12 +1033,12 @@ packages:
fast-json-stable-stringify@2.1.0: fast-json-stable-stringify@2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
fast-json-stringify@5.16.1: fast-json-stringify@6.0.1:
resolution: {integrity: sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==} resolution: {integrity: sha512-s7SJE83QKBZwg54dIbD5rCtzOBVD43V1ReWXXYqBgwCwHLYAAT0RQc/FmrQglXqWPpz6omtryJQOau5jI4Nrvg==}
fast-jwt@4.0.5: fast-jwt@5.0.5:
resolution: {integrity: sha512-QnpNdn0955GT7SlT8iMgYfhTsityUWysrQjM+Q7bGFijLp6+TNWzlbSMPvgalbrQGRg4ZaHZgMcns5fYOm5avg==} resolution: {integrity: sha512-Ch94zewwBjRznO0r76NFI5FDT0lOtnzkWVO4r7+d7E2WKuf7WW1FVOWRpv7QGEFlXzz9OAayrb5BhEmkOkwjhg==}
engines: {node: '>=16'} engines: {node: '>=20'}
fast-levenshtein@2.0.6: fast-levenshtein@2.0.6:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
@ -1067,9 +1050,6 @@ packages:
resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==}
engines: {node: '>=6'} engines: {node: '>=6'}
fast-uri@2.4.0:
resolution: {integrity: sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==}
fast-uri@3.0.6: fast-uri@3.0.6:
resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==}
@ -1077,11 +1057,11 @@ packages:
resolution: {integrity: sha512-KH6p+Z8AKPXnmA7+Iz2Lh8ARCMr+8WNPVludm1LGkZoD2MjY6LVnRMtTKhkdzI+jr0RzQWXKzKyBJm1zoHEL4Q==} resolution: {integrity: sha512-KH6p+Z8AKPXnmA7+Iz2Lh8ARCMr+8WNPVludm1LGkZoD2MjY6LVnRMtTKhkdzI+jr0RzQWXKzKyBJm1zoHEL4Q==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
fastify-plugin@4.5.1: fastify-plugin@5.0.1:
resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==} resolution: {integrity: sha512-HCxs+YnRaWzCl+cWRYFnHmeRFyR5GVnJTAaCJQiYzQSDwK9MgJdyAsuL3nh0EWRCYMgQ5MeziymvmAhUHYHDUQ==}
fastify@4.29.0: fastify@5.2.1:
resolution: {integrity: sha512-MaaUHUGcCgC8fXQDsDtioaCcag1fmPJ9j64vAKunqZF4aSub040ZGi/ag8NGE2714yREPOKZuHCfpPzuUD3UQQ==} resolution: {integrity: sha512-rslrNBF67eg8/Gyn7P2URV8/6pz8kSAscFL4EThZJ8JBMaXacVdVE4hmUcnPNKERl5o/xTiBSLfdowBRhVF1WA==}
fastparallel@2.4.1: fastparallel@2.4.1:
resolution: {integrity: sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q==} resolution: {integrity: sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q==}
@ -1112,8 +1092,8 @@ packages:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'} engines: {node: '>=8'}
find-my-way@8.2.2: find-my-way@9.1.0:
resolution: {integrity: sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==} resolution: {integrity: sha512-Y5jIsuYR4BwWDYYQ2A/RWWE6gD8a0FMgtU+HOq1WKku+Cwdz8M1v8wcAmRXXM1/iqtoqg06v+LjAxMYbCjViMw==}
engines: {node: '>=14'} engines: {node: '>=14'}
find-up@2.1.0: find-up@2.1.0:
@ -1139,10 +1119,6 @@ packages:
resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
engines: {node: '>=14'} engines: {node: '>=14'}
forwarded@0.2.0:
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
engines: {node: '>= 0.6'}
fs-extra@10.1.0: fs-extra@10.1.0:
resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -1307,9 +1283,9 @@ packages:
resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==}
engines: {node: '>=8.0.0'} engines: {node: '>=8.0.0'}
ipaddr.js@1.9.1: ipaddr.js@2.2.0:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==}
engines: {node: '>= 0.10'} engines: {node: '>= 10'}
is-arrayish@0.2.1: is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
@ -1391,9 +1367,6 @@ packages:
jackspeak@3.4.3: jackspeak@3.4.3:
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
joi@17.13.3:
resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==}
js-tokens@4.0.0: js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@ -1414,8 +1387,8 @@ packages:
json-parse-even-better-errors@2.3.1: json-parse-even-better-errors@2.3.1:
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
json-schema-ref-resolver@1.0.1: json-schema-ref-resolver@2.0.1:
resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} resolution: {integrity: sha512-HG0SIB9X4J8bwbxCbnd5FfPEbcXAJYTi1pBJeP/QPON+w8ovSME8iRG+ElHNxZNX2Qh6eYn1GdzJFS4cDFfx0Q==}
json-schema-traverse@0.4.1: json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
@ -1458,8 +1431,8 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
light-my-request@5.14.0: light-my-request@6.5.1:
resolution: {integrity: sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==} resolution: {integrity: sha512-0q82RyxIextuDtkA0UDofhPHIiQ2kmpa7fwElCSlm/8nQl36cDU1Cw+CAO90Es0lReH2HChClKL84I86Nc52hg==}
lilconfig@2.1.0: lilconfig@2.1.0:
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
@ -1667,6 +1640,9 @@ packages:
resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
hasBin: true hasBin: true
node-int64@0.4.0:
resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
nodemon@2.0.22: nodemon@2.0.22:
resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==} resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==}
engines: {node: '>=8.10.0'} engines: {node: '>=8.10.0'}
@ -1869,9 +1845,6 @@ packages:
process-nextick-args@2.0.1: process-nextick-args@2.0.1:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
process-warning@3.0.0:
resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==}
process-warning@4.0.1: process-warning@4.0.1:
resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==}
@ -1879,10 +1852,6 @@ packages:
resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
engines: {node: '>= 0.6.0'} engines: {node: '>= 0.6.0'}
proxy-addr@2.0.7:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
pstree.remy@1.1.8: pstree.remy@1.1.8:
resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==}
@ -1993,8 +1962,8 @@ packages:
resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==}
engines: {node: '>=18'} engines: {node: '>=18'}
ret@0.4.3: ret@0.5.0:
resolution: {integrity: sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==} resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==}
engines: {node: '>=10'} engines: {node: '>=10'}
reusify@1.0.4: reusify@1.0.4:
@ -2026,8 +1995,8 @@ packages:
safe-buffer@5.2.1: safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
safe-regex2@3.1.0: safe-regex2@4.0.1:
resolution: {integrity: sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==} resolution: {integrity: sha512-goqsB+bSlOmVX+CiFX2PFc1OV88j5jvBqIM+DgqrucHnUguAUNtiNOs+aTadq2NqsLQ+TQ3UEVG3gtSFcdlkCg==}
safe-stable-stringify@2.5.0: safe-stable-stringify@2.5.0:
resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
@ -2036,8 +2005,8 @@ packages:
safer-buffer@2.1.2: safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
secure-json-parse@2.7.0: secure-json-parse@3.0.2:
resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} resolution: {integrity: sha512-H6nS2o8bWfpFEV6U38sOSjS7bTbdgbCGU9wEM6W14P5H0QOsz94KCusifV44GpHDTu2nqZbuDNhTzu+mjDSw1w==}
semver@5.7.2: semver@5.7.2:
resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
@ -2086,9 +2055,6 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'} engines: {node: '>=14'}
simple-oauth2@5.1.0:
resolution: {integrity: sha512-gWDa38Ccm4MwlG5U7AlcJxPv3lvr80dU7ARJWrGdgvOKyzSj1gr3GBPN1rABTedAYvC/LsGYoFuFxwDBPtGEbw==}
simple-update-notifier@1.1.0: simple-update-notifier@1.1.0:
resolution: {integrity: sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==} resolution: {integrity: sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==}
engines: {node: '>=8.10.0'} engines: {node: '>=8.10.0'}
@ -2350,6 +2316,9 @@ packages:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
unzipper@0.12.3:
resolution: {integrity: sha512-PZ8hTS+AqcGxsaQntl3IRBw65QrBI6lxzqDEL7IAo/XCEqRTKGfOX56Vea5TH9SZczRVxuzk1re04z/YjuYCJA==}
uri-js@4.4.1: uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
@ -2705,62 +2674,53 @@ snapshots:
'@eslint/js@8.57.1': {} '@eslint/js@8.57.1': {}
'@fastify/ajv-compiler@3.6.0': '@fastify/ajv-compiler@4.0.2':
dependencies: dependencies:
ajv: 8.17.1 ajv: 8.17.1
ajv-formats: 2.1.1(ajv@8.17.1) ajv-formats: 3.0.1(ajv@8.17.1)
fast-uri: 2.4.0 fast-uri: 3.0.6
'@fastify/cookie@9.4.0': '@fastify/busboy@3.1.1': {}
'@fastify/cookie@11.0.2':
dependencies: dependencies:
cookie-signature: 1.2.2 cookie: 1.0.2
fastify-plugin: 4.5.1 fastify-plugin: 5.0.1
'@fastify/error@3.4.1': {} '@fastify/deepmerge@2.0.2': {}
'@fastify/fast-json-stringify-compiler@4.3.0': '@fastify/error@4.0.0': {}
'@fastify/fast-json-stringify-compiler@5.0.2':
dependencies: dependencies:
fast-json-stringify: 5.16.1 fast-json-stringify: 6.0.1
'@fastify/jwt@8.0.1': '@fastify/forwarded@3.0.0': {}
'@fastify/jwt@9.0.3':
dependencies: dependencies:
'@fastify/error': 3.4.1 '@fastify/error': 4.0.0
'@lukeed/ms': 2.0.2 '@lukeed/ms': 2.0.2
fast-jwt: 4.0.5 fast-jwt: 5.0.5
fastify-plugin: 4.5.1 fastify-plugin: 5.0.1
steed: 1.1.3 steed: 1.1.3
'@fastify/merge-json-schemas@0.1.1': '@fastify/merge-json-schemas@0.2.1':
dependencies: dependencies:
fast-deep-equal: 3.1.3 dequal: 2.0.3
'@fastify/oauth2@7.9.0': '@fastify/multipart@9.0.3':
dependencies: dependencies:
'@fastify/cookie': 9.4.0 '@fastify/busboy': 3.1.1
fastify-plugin: 4.5.1 '@fastify/deepmerge': 2.0.2
simple-oauth2: 5.1.0 '@fastify/error': 4.0.0
transitivePeerDependencies: fastify-plugin: 5.0.1
- supports-color secure-json-parse: 3.0.2
'@hapi/boom@10.0.1': '@fastify/proxy-addr@5.0.0':
dependencies: dependencies:
'@hapi/hoek': 11.0.7 '@fastify/forwarded': 3.0.0
ipaddr.js: 2.2.0
'@hapi/bourne@3.0.0': {}
'@hapi/hoek@11.0.7': {}
'@hapi/hoek@9.3.0': {}
'@hapi/topo@5.1.0':
dependencies:
'@hapi/hoek': 9.3.0
'@hapi/wreck@18.1.0':
dependencies:
'@hapi/boom': 10.0.1
'@hapi/bourne': 3.0.0
'@hapi/hoek': 11.0.7
'@humanwhocodes/config-array@0.13.0': '@humanwhocodes/config-array@0.13.0':
dependencies: dependencies:
@ -2830,14 +2790,6 @@ snapshots:
'@sapphire/snowflake@3.5.3': {} '@sapphire/snowflake@3.5.3': {}
'@sideway/address@4.1.5':
dependencies:
'@hapi/hoek': 9.3.0
'@sideway/formula@3.0.1': {}
'@sideway/pinpoint@2.0.0': {}
'@tsconfig/node10@1.0.11': {} '@tsconfig/node10@1.0.11': {}
'@tsconfig/node12@1.0.11': {} '@tsconfig/node12@1.0.11': {}
@ -2887,10 +2839,6 @@ snapshots:
add-stream@1.0.0: {} add-stream@1.0.0: {}
ajv-formats@2.1.1(ajv@8.17.1):
optionalDependencies:
ajv: 8.17.1
ajv-formats@3.0.1(ajv@8.17.1): ajv-formats@3.0.1(ajv@8.17.1):
optionalDependencies: optionalDependencies:
ajv: 8.17.1 ajv: 8.17.1
@ -2992,9 +2940,9 @@ snapshots:
atomic-sleep@1.0.0: {} atomic-sleep@1.0.0: {}
avvio@8.4.0: avvio@9.1.0:
dependencies: dependencies:
'@fastify/error': 3.4.1 '@fastify/error': 4.0.0
fastq: 1.18.0 fastq: 1.18.0
b4a@1.6.7: {} b4a@1.6.7: {}
@ -3013,6 +2961,8 @@ snapshots:
file-uri-to-path: 1.0.0 file-uri-to-path: 1.0.0
optional: true optional: true
bluebird@3.7.2: {}
bn.js@4.12.1: {} bn.js@4.12.1: {}
boxen@7.1.1: boxen@7.1.1:
@ -3276,9 +3226,7 @@ snapshots:
meow: 8.1.2 meow: 8.1.2
split2: 3.2.2 split2: 3.2.2
cookie-signature@1.2.2: {} cookie@1.0.2: {}
cookie@0.7.2: {}
core-util-is@1.0.3: {} core-util-is@1.0.3: {}
@ -3342,6 +3290,8 @@ snapshots:
deep-is@0.1.4: {} deep-is@0.1.4: {}
dequal@2.0.3: {}
didyoumean@1.2.2: {} didyoumean@1.2.2: {}
diff@4.0.2: {} diff@4.0.2: {}
@ -3376,6 +3326,10 @@ snapshots:
dotenv@16.4.7: {} dotenv@16.4.7: {}
duplexer2@0.1.4:
dependencies:
readable-stream: 2.3.8
eastasianwidth@0.2.0: {} eastasianwidth@0.2.0: {}
ecdsa-sig-formatter@1.0.11: ecdsa-sig-formatter@1.0.11:
@ -3518,8 +3472,6 @@ snapshots:
iconv-lite: 0.4.24 iconv-lite: 0.4.24
tmp: 0.0.33 tmp: 0.0.33
fast-content-type-parse@1.1.0: {}
fast-decode-uri-component@1.0.1: {} fast-decode-uri-component@1.0.1: {}
fast-deep-equal@3.1.3: {} fast-deep-equal@3.1.3: {}
@ -3528,17 +3480,16 @@ snapshots:
fast-json-stable-stringify@2.1.0: {} fast-json-stable-stringify@2.1.0: {}
fast-json-stringify@5.16.1: fast-json-stringify@6.0.1:
dependencies: dependencies:
'@fastify/merge-json-schemas': 0.1.1 '@fastify/merge-json-schemas': 0.2.1
ajv: 8.17.1 ajv: 8.17.1
ajv-formats: 3.0.1(ajv@8.17.1) ajv-formats: 3.0.1(ajv@8.17.1)
fast-deep-equal: 3.1.3 fast-uri: 3.0.6
fast-uri: 2.4.0 json-schema-ref-resolver: 2.0.1
json-schema-ref-resolver: 1.0.1
rfdc: 1.4.1 rfdc: 1.4.1
fast-jwt@4.0.5: fast-jwt@5.0.5:
dependencies: dependencies:
'@lukeed/ms': 2.0.2 '@lukeed/ms': 2.0.2
asn1.js: 5.4.1 asn1.js: 5.4.1
@ -3553,32 +3504,29 @@ snapshots:
fast-redact@3.5.0: {} fast-redact@3.5.0: {}
fast-uri@2.4.0: {}
fast-uri@3.0.6: {} fast-uri@3.0.6: {}
fastfall@1.5.1: fastfall@1.5.1:
dependencies: dependencies:
reusify: 1.0.4 reusify: 1.0.4
fastify-plugin@4.5.1: {} fastify-plugin@5.0.1: {}
fastify@4.29.0: fastify@5.2.1:
dependencies: dependencies:
'@fastify/ajv-compiler': 3.6.0 '@fastify/ajv-compiler': 4.0.2
'@fastify/error': 3.4.1 '@fastify/error': 4.0.0
'@fastify/fast-json-stringify-compiler': 4.3.0 '@fastify/fast-json-stringify-compiler': 5.0.2
'@fastify/proxy-addr': 5.0.0
abstract-logging: 2.0.1 abstract-logging: 2.0.1
avvio: 8.4.0 avvio: 9.1.0
fast-content-type-parse: 1.1.0 fast-json-stringify: 6.0.1
fast-json-stringify: 5.16.1 find-my-way: 9.1.0
find-my-way: 8.2.2 light-my-request: 6.5.1
light-my-request: 5.14.0
pino: 9.6.0 pino: 9.6.0
process-warning: 3.0.0 process-warning: 4.0.1
proxy-addr: 2.0.7
rfdc: 1.4.1 rfdc: 1.4.1
secure-json-parse: 2.7.0 secure-json-parse: 3.0.2
semver: 7.7.0 semver: 7.7.0
toad-cache: 3.7.0 toad-cache: 3.7.0
@ -3613,11 +3561,11 @@ snapshots:
dependencies: dependencies:
to-regex-range: 5.0.1 to-regex-range: 5.0.1
find-my-way@8.2.2: find-my-way@9.1.0:
dependencies: dependencies:
fast-deep-equal: 3.1.3 fast-deep-equal: 3.1.3
fast-querystring: 1.1.2 fast-querystring: 1.1.2
safe-regex2: 3.1.0 safe-regex2: 4.0.1
find-up@2.1.0: find-up@2.1.0:
dependencies: dependencies:
@ -3646,8 +3594,6 @@ snapshots:
cross-spawn: 7.0.6 cross-spawn: 7.0.6
signal-exit: 4.1.0 signal-exit: 4.1.0
forwarded@0.2.0: {}
fs-extra@10.1.0: fs-extra@10.1.0:
dependencies: dependencies:
graceful-fs: 4.2.11 graceful-fs: 4.2.11
@ -3815,7 +3761,7 @@ snapshots:
strip-ansi: 6.0.1 strip-ansi: 6.0.1
through: 2.3.8 through: 2.3.8
ipaddr.js@1.9.1: {} ipaddr.js@2.2.0: {}
is-arrayish@0.2.1: {} is-arrayish@0.2.1: {}
@ -3871,14 +3817,6 @@ snapshots:
optionalDependencies: optionalDependencies:
'@pkgjs/parseargs': 0.11.0 '@pkgjs/parseargs': 0.11.0
joi@17.13.3:
dependencies:
'@hapi/hoek': 9.3.0
'@hapi/topo': 5.1.0
'@sideway/address': 4.1.5
'@sideway/formula': 3.0.1
'@sideway/pinpoint': 2.0.0
js-tokens@4.0.0: {} js-tokens@4.0.0: {}
js-yaml@4.1.0: js-yaml@4.1.0:
@ -3897,9 +3835,9 @@ snapshots:
json-parse-even-better-errors@2.3.1: {} json-parse-even-better-errors@2.3.1: {}
json-schema-ref-resolver@1.0.1: json-schema-ref-resolver@2.0.1:
dependencies: dependencies:
fast-deep-equal: 3.1.3 dequal: 2.0.3
json-schema-traverse@0.4.1: {} json-schema-traverse@0.4.1: {}
@ -3940,10 +3878,10 @@ snapshots:
prelude-ls: 1.2.1 prelude-ls: 1.2.1
type-check: 0.4.0 type-check: 0.4.0
light-my-request@5.14.0: light-my-request@6.5.1:
dependencies: dependencies:
cookie: 0.7.2 cookie: 1.0.2
process-warning: 3.0.0 process-warning: 4.0.1
set-cookie-parser: 2.7.1 set-cookie-parser: 2.7.1
lilconfig@2.1.0: {} lilconfig@2.1.0: {}
@ -4137,6 +4075,8 @@ snapshots:
node-gyp-build@4.8.4: node-gyp-build@4.8.4:
optional: true optional: true
node-int64@0.4.0: {}
nodemon@2.0.22: nodemon@2.0.22:
dependencies: dependencies:
chokidar: 3.6.0 chokidar: 3.6.0
@ -4335,17 +4275,10 @@ snapshots:
process-nextick-args@2.0.1: {} process-nextick-args@2.0.1: {}
process-warning@3.0.0: {}
process-warning@4.0.1: {} process-warning@4.0.1: {}
process@0.11.10: {} process@0.11.10: {}
proxy-addr@2.0.7:
dependencies:
forwarded: 0.2.0
ipaddr.js: 1.9.1
pstree.remy@1.1.8: {} pstree.remy@1.1.8: {}
punycode@2.3.1: {} punycode@2.3.1: {}
@ -4458,7 +4391,7 @@ snapshots:
onetime: 7.0.0 onetime: 7.0.0
signal-exit: 4.1.0 signal-exit: 4.1.0
ret@0.4.3: {} ret@0.5.0: {}
reusify@1.0.4: {} reusify@1.0.4: {}
@ -4482,15 +4415,15 @@ snapshots:
safe-buffer@5.2.1: {} safe-buffer@5.2.1: {}
safe-regex2@3.1.0: safe-regex2@4.0.1:
dependencies: dependencies:
ret: 0.4.3 ret: 0.5.0
safe-stable-stringify@2.5.0: {} safe-stable-stringify@2.5.0: {}
safer-buffer@2.1.2: {} safer-buffer@2.1.2: {}
secure-json-parse@2.7.0: {} secure-json-parse@3.0.2: {}
semver@5.7.2: {} semver@5.7.2: {}
@ -4520,15 +4453,6 @@ snapshots:
signal-exit@4.1.0: {} signal-exit@4.1.0: {}
simple-oauth2@5.1.0:
dependencies:
'@hapi/hoek': 11.0.7
'@hapi/wreck': 18.1.0
debug: 4.4.0
joi: 17.13.3
transitivePeerDependencies:
- supports-color
simple-update-notifier@1.1.0: simple-update-notifier@1.1.0:
dependencies: dependencies:
semver: 7.0.0 semver: 7.0.0
@ -4778,6 +4702,14 @@ snapshots:
universalify@2.0.1: {} universalify@2.0.1: {}
unzipper@0.12.3:
dependencies:
bluebird: 3.7.2
duplexer2: 0.1.4
fs-extra: 11.3.0
graceful-fs: 4.2.11
node-int64: 0.4.0
uri-js@4.4.1: uri-js@4.4.1:
dependencies: dependencies:
punycode: 2.3.1 punycode: 2.3.1

View File

@ -1,14 +1,16 @@
const fastify = require('fastify')({ trustProxy: process.env.HTTP_TRUST_PROXY === 'true' }); const fastify = require('fastify')({ trustProxy: process.env.HTTP_TRUST_PROXY === 'true' });
const oauth = require('@fastify/oauth2');
const { randomBytes } = require('crypto');
const { short } = require('leeks.js'); const { short } = require('leeks.js');
const { join } = require('path'); const { join } = require('path');
const { files } = require('node-dir'); const { files } = require('node-dir');
const { getPrivilegeLevel } = require('./lib/users'); const { getPrivilegeLevel } = require('./lib/users');
const { format } = require('util');
process.env.ORIGIN = process.env.HTTP_INTERNAL || process.env.HTTP_EXTERNAL; process.env.ORIGIN = process.env.HTTP_INTERNAL || process.env.HTTP_EXTERNAL;
module.exports = async client => { module.exports = async client => {
// for file uploads
fastify.register(require('@fastify/multipart'), { limits: { fileSize: 2**27 } }); // 128 MiB
// cookies plugin, must be registered before oauth2 since oauth2@7.2.0 // cookies plugin, must be registered before oauth2 since oauth2@7.2.0
fastify.register(require('@fastify/cookie')); fastify.register(require('@fastify/cookie'));
@ -21,36 +23,6 @@ module.exports = async client => {
secret: process.env.ENCRYPTION_KEY, secret: process.env.ENCRYPTION_KEY,
}); });
// oauth2 plugin
fastify.states = new Map();
fastify.register(oauth, {
callbackUri: `${process.env.HTTP_EXTERNAL}/auth/callback`,
callbackUriParams: { prompt: 'none' },
checkStateFunction: async req => {
if (req.query.state !== req.cookies['oauth2-redirect-state']) {
throw new Error('Invalid state');
}
return true;
},
credentials: {
auth: oauth.DISCORD_CONFIGURATION,
client: {
id: client.user.id,
secret: process.env.DISCORD_SECRET,
},
},
generateStateFunction: req => {
const state = randomBytes(8).toString('hex');
fastify.states.set(state, req.query.r);
return state;
},
name: 'discord',
redirectStateCookieName: 'oauth2-redirect-state',
scope: ['applications.commands.permissions.update', 'guilds', 'identify'],
startRedirectPath: '/auth/login',
});
// auth // auth
fastify.decorate('authenticate', async (req, res) => { fastify.decorate('authenticate', async (req, res) => {
try { try {
@ -111,7 +83,14 @@ module.exports = async client => {
error: 'Unavailable For Legal Reasons', error: 'Unavailable For Legal Reasons',
message: 'This guild has been banned for breaking the terms of service.', message: 'This guild has been banned for breaking the terms of service.',
statusCode: 451, statusCode: 451,
});
}
if (!req.user.scopes?.includes('applications.commands.permissions.update')) {
return res.code(401).send({
elevate: 'admin',
error: 'Unauthorised',
message: 'Extra scopes required; reauthenticate.',
statusCode: 401,
}); });
} }
const guildMember = await guild.members.fetch(userId); const guildMember = await guild.members.fetch(userId);
@ -161,11 +140,15 @@ module.exports = async client => {
: '&a') + responseTime + 'ms'; : '&a') + responseTime + 'ms';
const level = req.routeOptions.url === '/status' const level = req.routeOptions.url === '/status'
? 'debug' ? 'debug'
: req.routeOptions.url === '/*' : req.routeOptions.url === '/*'
? 'verbose' ? 'verbose'
: 'info'; : 'info';
client.log[level].http(short(`${req.id} ${req.ip} ${req.method} ${req.routeOptions.url ?? '*'} &m-+>&r ${status}&b in ${responseTime}`)); client.log[level].http(
if (!req.routeOptions.url) client.log.verbose.http(`${req.id} ${req.method} ${req.url}`); format(
short(`${req.id} ${req.ip} ${req.method} %s &m-+>&r ${status}&b in ${responseTime}`),
req.url,
),
);
done(); done();
}); });

View File

@ -1 +0,0 @@
module.exports.domain = new URL(process.env.HTTP_EXTERNAL).hostname;

View File

@ -1,7 +1,27 @@
const { domain } = require('../../lib/http');
module.exports.get = () => ({ module.exports.get = () => ({
handler: async function (req, res) { // MUST NOT use arrow function syntax handler: async function (req, res) {
const cookie = req.cookies['oauth2-state'];
if (!cookie) {
return res.code(400).send({
error: 'Bad Request',
message: 'State is missing.',
statusCode: 400,
});
}
const state = new URLSearchParams(cookie);
if (state.get('secret') !== req.query.state) {
return res.code(400).send({
error: 'Bad Request',
message: 'Invalid state.',
statusCode: 400,
});
}
// TODO: check if req.query.permissions are correct
const data = await (await fetch('https://discord.com/api/oauth2/token', { const data = await (await fetch('https://discord.com/api/oauth2/token', {
body: new URLSearchParams({ body: new URLSearchParams({
client_id: req.routeOptions.config.client.user.id, client_id: req.routeOptions.config.client.user.id,
@ -14,22 +34,30 @@ module.exports.get = () => ({
method: 'POST', method: 'POST',
})).json(); })).json();
const user = await (await fetch('https://discordapp.com/api/users/@me', { headers: { 'Authorization': `Bearer ${data.access_token}` } })).json(); const redirect = (data.guild?.id && `/settings/${data.guild?.id}`) || state.get('redirect') || '/';
const bearerOptions = { headers: { 'Authorization': `Bearer ${data.access_token}` } };
const user = await (await fetch('https://discordapp.com/api/users/@me', bearerOptions)).json();
let scopes;
if (data.scope) {
scopes = data.scope.split(' ');
} else {
const auth = await (await fetch('https://discordapp.com/api/oauth2/@me', bearerOptions)).json();
scopes = auth.scopes;
}
const token = this.jwt.sign({ const token = this.jwt.sign({
accessToken: data.access_token, accessToken: data.access_token,
avatar: user.avatar, avatar: user.avatar,
expiresAt: Date.now() + (data.expires_in * 1000), expiresAt: Date.now() + (data.expires_in * 1000),
id: user.id, id: user.id,
locale: user.locale, locale: user.locale,
scopes,
username: user.username, username: user.username,
}); });
// note: if data.guild is present, guild_id and permissions should also be in req.query
const redirect = this.states.get(req.query.state) || (data.guild?.id && `/settings/${data.guild?.id}`) || '/';
this.states.delete(req.query.state);
res.setCookie('token', token, { res.setCookie('token', token, {
domain,
httpOnly: true, httpOnly: true,
maxAge: data.expires_in, maxAge: data.expires_in,
path: '/', path: '/',

44
src/routes/auth/login.js Normal file
View File

@ -0,0 +1,44 @@
const { randomBytes } = require('crypto');
module.exports.get = () => ({
handler: async function (req, res) {
const { client } = req.routeOptions.config;
const state = new URLSearchParams({
redirect: req.query.r ?? '',
secret: randomBytes(8).toString('hex'),
});
res.setCookie('oauth2-state', state.toString(), {
httpOnly: true,
sameSite: 'lax',
});
const params = {
client_id: client.user.id,
// ? prompt: 'none',
redirect_uri: `${process.env.HTTP_EXTERNAL}/auth/callback`, // if not set defaults to first allowed
response_type: 'code',
scope: 'guilds identify',
state: state.get('secret'),
};
if (req.query.invite !== undefined) {
params.prompt = 'consent'; // already implied by the bot scope
params.scope = 'applications.commands applications.commands.permissions.update bot ' + params.scope;
params.integration_type = '0';
params.permissions = '268561488';
if (req.query.guild) {
params.guild_id = req.query.guild;
params.disable_guild_select = 'true';
}
} else if (req.query.role === 'admin') { // invite implies admin already
params.scope = 'applications.commands.permissions.update ' + params.scope;
}
const url = new URL('https://discord.com/oauth2/authorize');
url.search = new URLSearchParams(params);
res.redirect(url.toString());
},
});

View File

@ -1,5 +1,3 @@
const { domain } = require('../../lib/http');
module.exports.get = fastify => ({ module.exports.get = fastify => ({
handler: async function (req, res) { handler: async function (req, res) {
const { accessToken } = req.user; const { accessToken } = req.user;
@ -15,7 +13,6 @@ module.exports.get = fastify => ({
}); });
res.clearCookie('token', { res.clearCookie('token', {
domain,
httpOnly: true, httpOnly: true,
path: '/', path: '/',
sameSite: 'Strict', sameSite: 'Strict',

View File

@ -1,29 +1,5 @@
const { randomBytes } = require('crypto');
module.exports.get = () => ({ module.exports.get = () => ({
handler: async function (req, res) { handler: async function (req, res) {
const { client } = req.routeOptions.config; res.redirect(`/auth/login?invite&guild=${req.query.guild || ''}`);
const state = randomBytes(8).toString('hex');
this.states.set(state, null);
const url = new URL('https://discord.com/oauth2/authorize');
url.searchParams.set('response_type', 'code');
url.searchParams.set('client_id', client.user.id);
url.searchParams.set('prompt', 'none');
url.searchParams.set('redirect_uri', `${process.env.HTTP_EXTERNAL}/auth/callback`); // window.location.origin
url.searchParams.set('scope', 'applications.commands applications.commands.permissions.update bot guilds identify');
url.searchParams.set('permissions', '268561488');
if (req.query.guild) {
url.searchParams.set('guild_id', req.query.guild);
url.searchParams.set('disable_guild_select', 'true');
}
res.setCookie('oauth2-redirect-state', state, {
httpOnly: true,
sameSite: 'lax',
});
res.redirect(url.toString());
}, },
}); });