Merge branch 'main' into dev

This commit is contained in:
Owen
2025-09-28 11:39:38 -07:00
42 changed files with 430 additions and 279 deletions

View File

@@ -153,3 +153,5 @@ Looking for something to contribute? Take a look at issues marked with [help wan
Please see [CONTRIBUTING](./CONTRIBUTING.md) in the repository for guidelines and best practices.
Please post bug reports and other functional issues in the [Issues](https://github.com/fosrl/pangolin/issues) section of the repository.
If you are looking to help with translations, please contribute [on Crowdin](https://crowdin.com/project/fossorial-pangolin) or open a PR with changes to the translations files found in `messages/`.

View File

@@ -3,7 +3,7 @@
"setupNewOrg": "Nieuwe organisatie",
"setupCreateOrg": "Nieuwe organisatie aanmaken",
"setupCreateResources": "Bronnen aanmaken",
"setupOrgName": "Naam organisatie",
"setupOrgName": "Naam van de organisatie",
"orgDisplayName": "Dit is de weergavenaam van uw organisatie.",
"orgId": "Organisatie ID",
"setupIdentifierMessage": "Dit is de unieke identificatie voor uw organisatie. Deze is gescheiden van de weergavenaam.",
@@ -35,7 +35,7 @@
"createAccount": "Account Aanmaken",
"viewSettings": "Instellingen weergeven",
"delete": "Verwijderen",
"name": "naam",
"name": "Naam",
"online": "Online",
"offline": "Offline",
"site": "Website",
@@ -265,7 +265,7 @@
"apiKeysGeneralSettingsDescription": "Bepaal wat deze API-sleutel kan doen",
"apiKeysList": "Uw API-sleutel",
"apiKeysSave": "Uw API-sleutel opslaan",
"apiKeysSaveDescription": "Je kunt dit slechts één keer zien. Kopieer het naar een beveiligde plek.",
"apiKeysSaveDescription": "Je kunt dit slechts één keer zien. Kopieer het naar een veilige plek.",
"apiKeysInfo": "Uw API-sleutel is:",
"apiKeysConfirmCopy": "Ik heb de API-sleutel gekopieerd",
"generate": "Genereren",
@@ -994,7 +994,7 @@
"actionGetUser": "Gebruiker ophalen",
"actionGetOrgUser": "Krijg organisatie-gebruiker",
"actionListOrgDomains": "Lijst organisatie domeinen",
"actionCreateSite": "Site maken",
"actionCreateSite": "Site aanmaken",
"actionDeleteSite": "Site verwijderen",
"actionGetSite": "Site ophalen",
"actionListSites": "Sites weergeven",

386
package-lock.json generated
View File

@@ -10,7 +10,7 @@
"license": "SEE LICENSE IN LICENSE AND README.md",
"dependencies": {
"@asteasolutions/zod-to-openapi": "^7.3.4",
"@hookform/resolvers": "4.1.3",
"@hookform/resolvers": "5.2.2",
"@node-rs/argon2": "^2.0.2",
"@oslojs/crypto": "1.0.1",
"@oslojs/encoding": "1.1.0",
@@ -35,8 +35,8 @@
"@react-email/components": "0.5.3",
"@react-email/render": "^1.2.0",
"@react-email/tailwind": "1.2.2",
"@simplewebauthn/browser": "^13.1.2",
"@simplewebauthn/server": "^9.0.3",
"@simplewebauthn/browser": "^13.2.0",
"@simplewebauthn/server": "^13.2.1",
"@tailwindcss/forms": "^0.5.10",
"@tanstack/react-table": "8.21.3",
"arctic": "^3.7.0",
@@ -125,9 +125,9 @@
"react-email": "4.2.11",
"tailwindcss": "^4.1.4",
"tsc-alias": "1.8.16",
"tsx": "4.20.5",
"tsx": "4.20.6",
"typescript": "^5",
"typescript-eslint": "^8.44.0"
"typescript-eslint": "^8.44.1"
}
},
"node_modules/@alloc/quick-lru": {
@@ -2233,15 +2233,14 @@
"license": "MIT"
},
"node_modules/@hookform/resolvers": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-4.1.3.tgz",
"integrity": "sha512-Jsv6UOWYTrEFJ/01ZrnwVXs7KDvP8XIo115i++5PWvNkNvkrsTfGiLS6w+eJ57CYtUtDQalUWovCZDHFJ8u1VQ==",
"license": "MIT",
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.2.2.tgz",
"integrity": "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==",
"dependencies": {
"@standard-schema/utils": "^0.3.0"
},
"peerDependencies": {
"react-hook-form": "^7.0.0"
"react-hook-form": "^7.55.0"
}
},
"node_modules/@humanfs/core": {
@@ -3663,34 +3662,101 @@
"tslib": "^2.8.1"
}
},
"node_modules/@peculiar/asn1-ecc": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.4.0.tgz",
"integrity": "sha512-fJiYUBCJBDkjh347zZe5H81BdJ0+OGIg0X9z06v8xXUoql3MFeENUX0JsjCaVaU9A0L85PefLPGYkIoGpTnXLQ==",
"node_modules/@peculiar/asn1-cms": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.5.0.tgz",
"integrity": "sha512-p0SjJ3TuuleIvjPM4aYfvYw8Fk1Hn/zAVyPJZTtZ2eE9/MIer6/18ROxX6N/e6edVSfvuZBqhxAj3YgsmSjQ/A==",
"license": "MIT",
"dependencies": {
"@peculiar/asn1-schema": "^2.4.0",
"@peculiar/asn1-x509": "^2.4.0",
"@peculiar/asn1-schema": "^2.5.0",
"@peculiar/asn1-x509": "^2.5.0",
"@peculiar/asn1-x509-attr": "^2.5.0",
"asn1js": "^3.0.6",
"tslib": "^2.8.1"
}
},
"node_modules/@peculiar/asn1-csr": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.5.0.tgz",
"integrity": "sha512-ioigvA6WSYN9h/YssMmmoIwgl3RvZlAYx4A/9jD2qaqXZwGcNlAxaw54eSx2QG1Yu7YyBC5Rku3nNoHrQ16YsQ==",
"license": "MIT",
"dependencies": {
"@peculiar/asn1-schema": "^2.5.0",
"@peculiar/asn1-x509": "^2.5.0",
"asn1js": "^3.0.6",
"tslib": "^2.8.1"
}
},
"node_modules/@peculiar/asn1-ecc": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.5.0.tgz",
"integrity": "sha512-t4eYGNhXtLRxaP50h3sfO6aJebUCDGQACoeexcelL4roMFRRVgB20yBIu2LxsPh/tdW9I282gNgMOyg3ywg/mg==",
"license": "MIT",
"dependencies": {
"@peculiar/asn1-schema": "^2.5.0",
"@peculiar/asn1-x509": "^2.5.0",
"asn1js": "^3.0.6",
"tslib": "^2.8.1"
}
},
"node_modules/@peculiar/asn1-pfx": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.5.0.tgz",
"integrity": "sha512-Vj0d0wxJZA+Ztqfb7W+/iu8Uasw6hhKtCdLKXLG/P3kEPIQpqGI4P4YXlROfl7gOCqFIbgsj1HzFIFwQ5s20ug==",
"license": "MIT",
"dependencies": {
"@peculiar/asn1-cms": "^2.5.0",
"@peculiar/asn1-pkcs8": "^2.5.0",
"@peculiar/asn1-rsa": "^2.5.0",
"@peculiar/asn1-schema": "^2.5.0",
"asn1js": "^3.0.6",
"tslib": "^2.8.1"
}
},
"node_modules/@peculiar/asn1-pkcs8": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.5.0.tgz",
"integrity": "sha512-L7599HTI2SLlitlpEP8oAPaJgYssByI4eCwQq2C9eC90otFpm8MRn66PpbKviweAlhinWQ3ZjDD2KIVtx7PaVw==",
"license": "MIT",
"dependencies": {
"@peculiar/asn1-schema": "^2.5.0",
"@peculiar/asn1-x509": "^2.5.0",
"asn1js": "^3.0.6",
"tslib": "^2.8.1"
}
},
"node_modules/@peculiar/asn1-pkcs9": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.5.0.tgz",
"integrity": "sha512-UgqSMBLNLR5TzEZ5ZzxR45Nk6VJrammxd60WMSkofyNzd3DQLSNycGWSK5Xg3UTYbXcDFyG8pA/7/y/ztVCa6A==",
"license": "MIT",
"dependencies": {
"@peculiar/asn1-cms": "^2.5.0",
"@peculiar/asn1-pfx": "^2.5.0",
"@peculiar/asn1-pkcs8": "^2.5.0",
"@peculiar/asn1-schema": "^2.5.0",
"@peculiar/asn1-x509": "^2.5.0",
"@peculiar/asn1-x509-attr": "^2.5.0",
"asn1js": "^3.0.6",
"tslib": "^2.8.1"
}
},
"node_modules/@peculiar/asn1-rsa": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.4.0.tgz",
"integrity": "sha512-6PP75voaEnOSlWR9sD25iCQyLgFZHXbmxvUfnnDcfL6Zh5h2iHW38+bve4LfH7a60x7fkhZZNmiYqAlAff9Img==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.5.0.tgz",
"integrity": "sha512-qMZ/vweiTHy9syrkkqWFvbT3eLoedvamcUdnnvwyyUNv5FgFXA3KP8td+ATibnlZ0EANW5PYRm8E6MJzEB/72Q==",
"license": "MIT",
"dependencies": {
"@peculiar/asn1-schema": "^2.4.0",
"@peculiar/asn1-x509": "^2.4.0",
"@peculiar/asn1-schema": "^2.5.0",
"@peculiar/asn1-x509": "^2.5.0",
"asn1js": "^3.0.6",
"tslib": "^2.8.1"
}
},
"node_modules/@peculiar/asn1-schema": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.4.0.tgz",
"integrity": "sha512-umbembjIWOrPSOzEGG5vxFLkeM8kzIhLkgigtsOrfLKnuzxWxejAcUX+q/SoZCdemlODOcr5WiYa7+dIEzBXZQ==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.5.0.tgz",
"integrity": "sha512-YM/nFfskFJSlHqv59ed6dZlLZqtZQwjRVJ4bBAiWV08Oc+1rSd5lDZcBEx0lGDHfSoH3UziI2pXt2UM33KerPQ==",
"license": "MIT",
"dependencies": {
"asn1js": "^3.0.6",
@@ -3699,17 +3765,48 @@
}
},
"node_modules/@peculiar/asn1-x509": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.4.0.tgz",
"integrity": "sha512-F7mIZY2Eao2TaoVqigGMLv+NDdpwuBKU1fucHPONfzaBS4JXXCNCmfO0Z3dsy7JzKGqtDcYC1mr9JjaZQZNiuw==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.5.0.tgz",
"integrity": "sha512-CpwtMCTJvfvYTFMuiME5IH+8qmDe3yEWzKHe7OOADbGfq7ohxeLaXwQo0q4du3qs0AII3UbLCvb9NF/6q0oTKQ==",
"license": "MIT",
"dependencies": {
"@peculiar/asn1-schema": "^2.4.0",
"@peculiar/asn1-schema": "^2.5.0",
"asn1js": "^3.0.6",
"pvtsutils": "^1.3.6",
"tslib": "^2.8.1"
}
},
"node_modules/@peculiar/asn1-x509-attr": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.5.0.tgz",
"integrity": "sha512-9f0hPOxiJDoG/bfNLAFven+Bd4gwz/VzrCIIWc1025LEI4BXO0U5fOCTNDPbbp2ll+UzqKsZ3g61mpBp74gk9A==",
"license": "MIT",
"dependencies": {
"@peculiar/asn1-schema": "^2.5.0",
"@peculiar/asn1-x509": "^2.5.0",
"asn1js": "^3.0.6",
"tslib": "^2.8.1"
}
},
"node_modules/@peculiar/x509": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.0.tgz",
"integrity": "sha512-Yc4PDxN3OrxUPiXgU63c+ZRXKGE8YKF2McTciYhUHFtHVB0KMnjeFSU0qpztGhsp4P0uKix4+J2xEpIEDu8oXg==",
"license": "MIT",
"dependencies": {
"@peculiar/asn1-cms": "^2.5.0",
"@peculiar/asn1-csr": "^2.5.0",
"@peculiar/asn1-ecc": "^2.5.0",
"@peculiar/asn1-pkcs9": "^2.5.0",
"@peculiar/asn1-rsa": "^2.5.0",
"@peculiar/asn1-schema": "^2.5.0",
"@peculiar/asn1-x509": "^2.5.0",
"pvtsutils": "^1.3.6",
"reflect-metadata": "^0.2.2",
"tslib": "^2.8.1",
"tsyringe": "^4.10.0"
}
},
"node_modules/@posthog/core": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.0.2.tgz",
@@ -5102,15 +5199,15 @@
}
},
"node_modules/@simplewebauthn/browser": {
"version": "13.1.2",
"resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.1.2.tgz",
"integrity": "sha512-aZnW0KawAM83fSBUgglP5WofbrLbLyr7CoPqYr66Eppm7zO86YX6rrCjRB3hQKPrL7ATvY4FVXlykZ6w6FwYYw==",
"version": "13.2.0",
"resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.2.0.tgz",
"integrity": "sha512-N3fuA1AAnTo5gCStYoIoiasPccC+xPLx2YU88Dv0GeAmPQTWHETlZQq5xZ0DgUq1H9loXMWQH5qqUjcI7BHJ1A==",
"license": "MIT"
},
"node_modules/@simplewebauthn/server": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/@simplewebauthn/server/-/server-9.0.3.tgz",
"integrity": "sha512-FMZieoBosrVLFxCnxPFD9Enhd1U7D8nidVDT4MsHc6l4fdVcjoeHjDueeXCloO1k5O/fZg1fsSXXPKbY2XTzDA==",
"version": "13.2.1",
"resolved": "https://registry.npmjs.org/@simplewebauthn/server/-/server-13.2.1.tgz",
"integrity": "sha512-Inmfye5opZXe3HI0GaksqBnQiM7glcNySoG6DH1GgkO1Lh9dvuV4XSV9DK02DReUVX39HpcDob9nxHELjECoQw==",
"license": "MIT",
"dependencies": {
"@hexagon/base64": "^1.1.27",
@@ -5120,20 +5217,12 @@
"@peculiar/asn1-rsa": "^2.3.8",
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"@simplewebauthn/types": "^9.0.1",
"cross-fetch": "^4.0.0"
"@peculiar/x509": "^1.13.0"
},
"engines": {
"node": ">=16.0.0"
"node": ">=20.0.0"
}
},
"node_modules/@simplewebauthn/types": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/@simplewebauthn/types/-/types-9.0.1.tgz",
"integrity": "sha512-tGSRP1QvsAvsJmnOlRQyw/mvK9gnPtjEc5fg2+m8n+QUa+D7rvrKkOYyfpy42GTs90X3RDOnqJgfHt+qO67/+w==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"license": "MIT"
},
"node_modules/@smithy/abort-controller": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.1.1.tgz",
@@ -6490,16 +6579,16 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.0.tgz",
"integrity": "sha512-EGDAOGX+uwwekcS0iyxVDmRV9HX6FLSM5kzrAToLTsr9OWCIKG/y3lQheCq18yZ5Xh78rRKJiEpP0ZaCs4ryOQ==",
"version": "8.44.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.1.tgz",
"integrity": "sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==",
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.44.0",
"@typescript-eslint/type-utils": "8.44.0",
"@typescript-eslint/utils": "8.44.0",
"@typescript-eslint/visitor-keys": "8.44.0",
"@typescript-eslint/scope-manager": "8.44.1",
"@typescript-eslint/type-utils": "8.44.1",
"@typescript-eslint/utils": "8.44.1",
"@typescript-eslint/visitor-keys": "8.44.1",
"graphemer": "^1.4.0",
"ignore": "^7.0.0",
"natural-compare": "^1.4.0",
@@ -6513,7 +6602,7 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.44.0",
"@typescript-eslint/parser": "^8.44.1",
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
@@ -6528,15 +6617,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.0.tgz",
"integrity": "sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw==",
"version": "8.44.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.1.tgz",
"integrity": "sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==",
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.44.0",
"@typescript-eslint/types": "8.44.0",
"@typescript-eslint/typescript-estree": "8.44.0",
"@typescript-eslint/visitor-keys": "8.44.0",
"@typescript-eslint/scope-manager": "8.44.1",
"@typescript-eslint/types": "8.44.1",
"@typescript-eslint/typescript-estree": "8.44.1",
"@typescript-eslint/visitor-keys": "8.44.1",
"debug": "^4.3.4"
},
"engines": {
@@ -6552,13 +6641,13 @@
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.0.tgz",
"integrity": "sha512-ZeaGNraRsq10GuEohKTo4295Z/SuGcSq2LzfGlqiuEvfArzo/VRrT0ZaJsVPuKZ55lVbNk8U6FcL+ZMH8CoyVA==",
"version": "8.44.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.1.tgz",
"integrity": "sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==",
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.44.0",
"@typescript-eslint/types": "^8.44.0",
"@typescript-eslint/tsconfig-utils": "^8.44.1",
"@typescript-eslint/types": "^8.44.1",
"debug": "^4.3.4"
},
"engines": {
@@ -6573,13 +6662,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.0.tgz",
"integrity": "sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==",
"version": "8.44.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.1.tgz",
"integrity": "sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==",
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.44.0",
"@typescript-eslint/visitor-keys": "8.44.0"
"@typescript-eslint/types": "8.44.1",
"@typescript-eslint/visitor-keys": "8.44.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -6590,9 +6679,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.0.tgz",
"integrity": "sha512-x5Y0+AuEPqAInc6yd0n5DAcvtoQ/vyaGwuX5HE9n6qAefk1GaedqrLQF8kQGylLUb9pnZyLf+iEiL9fr8APDtQ==",
"version": "8.44.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.1.tgz",
"integrity": "sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==",
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -6606,14 +6695,14 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.0.tgz",
"integrity": "sha512-9cwsoSxJ8Sak67Be/hD2RNt/fsqmWnNE1iHohG8lxqLSNY8xNfyY7wloo5zpW3Nu9hxVgURevqfcH6vvKCt6yg==",
"version": "8.44.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.1.tgz",
"integrity": "sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==",
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.44.0",
"@typescript-eslint/typescript-estree": "8.44.0",
"@typescript-eslint/utils": "8.44.0",
"@typescript-eslint/types": "8.44.1",
"@typescript-eslint/typescript-estree": "8.44.1",
"@typescript-eslint/utils": "8.44.1",
"debug": "^4.3.4",
"ts-api-utils": "^2.1.0"
},
@@ -6630,9 +6719,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.0.tgz",
"integrity": "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==",
"version": "8.44.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.1.tgz",
"integrity": "sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==",
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -6643,15 +6732,15 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.0.tgz",
"integrity": "sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==",
"version": "8.44.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.1.tgz",
"integrity": "sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==",
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.44.0",
"@typescript-eslint/tsconfig-utils": "8.44.0",
"@typescript-eslint/types": "8.44.0",
"@typescript-eslint/visitor-keys": "8.44.0",
"@typescript-eslint/project-service": "8.44.1",
"@typescript-eslint/tsconfig-utils": "8.44.1",
"@typescript-eslint/types": "8.44.1",
"@typescript-eslint/visitor-keys": "8.44.1",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -6723,15 +6812,15 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.0.tgz",
"integrity": "sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==",
"version": "8.44.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.1.tgz",
"integrity": "sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==",
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.44.0",
"@typescript-eslint/types": "8.44.0",
"@typescript-eslint/typescript-estree": "8.44.0"
"@typescript-eslint/scope-manager": "8.44.1",
"@typescript-eslint/types": "8.44.1",
"@typescript-eslint/typescript-estree": "8.44.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -6746,12 +6835,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.0.tgz",
"integrity": "sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==",
"version": "8.44.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.1.tgz",
"integrity": "sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==",
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.44.0",
"@typescript-eslint/types": "8.44.1",
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
@@ -8079,35 +8168,6 @@
"node": ">= 0.10"
}
},
"node_modules/cross-fetch": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz",
"integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==",
"license": "MIT",
"dependencies": {
"node-fetch": "^2.7.0"
}
},
"node_modules/cross-fetch/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==",
"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_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -16205,6 +16265,12 @@
"node": ">=0.8.8"
}
},
"node_modules/reflect-metadata": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
"integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
"license": "Apache-2.0"
},
"node_modules/reflect.getprototypeof": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
@@ -17432,9 +17498,9 @@
}
},
"node_modules/tar-fs": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz",
"integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==",
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
"integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
"license": "MIT",
"dependencies": {
"chownr": "^1.1.1",
@@ -17515,12 +17581,6 @@
"node": ">=0.6"
}
},
"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/triple-beam": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
@@ -17666,9 +17726,9 @@
}
},
"node_modules/tsx": {
"version": "4.20.5",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.5.tgz",
"integrity": "sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==",
"version": "4.20.6",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz",
"integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -17685,6 +17745,24 @@
"fsevents": "~2.3.3"
}
},
"node_modules/tsyringe": {
"version": "4.10.0",
"resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz",
"integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==",
"license": "MIT",
"dependencies": {
"tslib": "^1.9.3"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/tsyringe/node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"license": "0BSD"
},
"node_modules/tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -17820,16 +17898,16 @@
}
},
"node_modules/typescript-eslint": {
"version": "8.44.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.44.0.tgz",
"integrity": "sha512-ib7mCkYuIzYonCq9XWF5XNw+fkj2zg629PSa9KNIQ47RXFF763S5BIX4wqz1+FLPogTZoiw8KmCiRPRa8bL3qw==",
"version": "8.44.1",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.44.1.tgz",
"integrity": "sha512-0ws8uWGrUVTjEeN2OM4K1pLKHK/4NiNP/vz6ns+LjT/6sqpaYzIVFajZb1fj/IDwpsrrHb3Jy0Qm5u9CPcKaeg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "8.44.0",
"@typescript-eslint/parser": "8.44.0",
"@typescript-eslint/typescript-estree": "8.44.0",
"@typescript-eslint/utils": "8.44.0"
"@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1",
"@typescript-eslint/typescript-estree": "8.44.1",
"@typescript-eslint/utils": "8.44.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -18036,22 +18114,6 @@
"node": ">= 8"
}
},
"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/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/which": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",

View File

@@ -27,7 +27,7 @@
},
"dependencies": {
"@asteasolutions/zod-to-openapi": "^7.3.4",
"@hookform/resolvers": "4.1.3",
"@hookform/resolvers": "5.2.2",
"@node-rs/argon2": "^2.0.2",
"@oslojs/crypto": "1.0.1",
"@oslojs/encoding": "1.1.0",
@@ -52,8 +52,8 @@
"@react-email/components": "0.5.3",
"@react-email/render": "^1.2.0",
"@react-email/tailwind": "1.2.2",
"@simplewebauthn/browser": "^13.1.2",
"@simplewebauthn/server": "^9.0.3",
"@simplewebauthn/browser": "^13.2.0",
"@simplewebauthn/server": "^13.2.1",
"@tailwindcss/forms": "^0.5.10",
"@tanstack/react-table": "8.21.3",
"arctic": "^3.7.0",
@@ -142,9 +142,9 @@
"react-email": "4.2.11",
"tailwindcss": "^4.1.4",
"tsc-alias": "1.8.16",
"tsx": "4.20.5",
"tsx": "4.20.6",
"typescript": "^5",
"typescript-eslint": "^8.44.0"
"typescript-eslint": "^8.44.1"
},
"overrides": {
"emblor": {

View File

@@ -2,7 +2,7 @@ import path from "path";
import { fileURLToPath } from "url";
// This is a placeholder value replaced by the build process
export const APP_VERSION = "1.10.2";
export const APP_VERSION = "1.10.4";
export const __FILENAME = fileURLToPath(import.meta.url);
export const __DIRNAME = path.dirname(__FILENAME);

View File

@@ -16,18 +16,12 @@ import {
} from "@simplewebauthn/server";
import type {
GenerateRegistrationOptionsOpts,
VerifyRegistrationResponseOpts,
GenerateAuthenticationOptionsOpts,
VerifyAuthenticationResponseOpts,
VerifiedRegistrationResponse,
VerifiedAuthenticationResponse
AuthenticatorTransportFuture
} from "@simplewebauthn/server";
import type {
AuthenticatorTransport,
AuthenticatorTransportFuture,
PublicKeyCredentialDescriptorJSON,
PublicKeyCredentialDescriptorFuture
} from "@simplewebauthn/types";
import {
isoBase64URL
} from '@simplewebauthn/server/helpers';
import config from "@server/lib/config";
import { UserType } from "@server/types/UserTypes";
import { verifyPassword } from "@server/auth/password";
@@ -204,15 +198,14 @@ export async function startRegistration(
.where(eq(securityKeys.userId, user.userId));
const excludeCredentials = existingSecurityKeys.map(key => ({
id: new Uint8Array(Buffer.from(key.credentialId, 'base64')),
type: 'public-key' as const,
id: key.credentialId,
transports: key.transports ? JSON.parse(key.transports) as AuthenticatorTransportFuture[] : undefined
}));
const options: GenerateRegistrationOptionsOpts = {
rpName,
rpID,
userID: user.userId,
userID: isoBase64URL.toBuffer(user.userId),
userName: user.email || user.username,
attestationType: 'none',
excludeCredentials,
@@ -308,11 +301,11 @@ export async function verifyRegistration(
// Store the security key in the database
await db.insert(securityKeys).values({
credentialId: Buffer.from(registrationInfo.credentialID).toString('base64'),
credentialId: registrationInfo.credential.id,
userId: user.userId,
publicKey: Buffer.from(registrationInfo.credentialPublicKey).toString('base64'),
signCount: registrationInfo.counter || 0,
transports: credential.response.transports ? JSON.stringify(credential.response.transports) : null,
publicKey: isoBase64URL.fromBuffer(registrationInfo.credential.publicKey),
signCount: registrationInfo.credential.counter || 0,
transports: registrationInfo.credential.transports ? JSON.stringify(registrationInfo.credential.transports) : null,
name: challengeData.securityKeyName,
lastUsed: new Date().toISOString(),
dateCreated: new Date().toISOString()
@@ -496,7 +489,7 @@ export async function startAuthentication(
const { email } = parsedBody.data;
try {
let allowCredentials: PublicKeyCredentialDescriptorFuture[] = [];
let allowCredentials;
let userId;
// If email is provided, get security keys for that specific user
@@ -533,13 +526,9 @@ export async function startAuthentication(
}
allowCredentials = userSecurityKeys.map(key => ({
id: new Uint8Array(Buffer.from(key.credentialId, 'base64')),
type: 'public-key' as const,
id: key.credentialId,
transports: key.transports ? JSON.parse(key.transports) as AuthenticatorTransportFuture[] : undefined
}));
} else {
// If no email provided, allow any security key (for resident key authentication)
allowCredentials = [];
}
const options: GenerateAuthenticationOptionsOpts = {
@@ -616,7 +605,7 @@ export async function verifyAuthentication(
}
// Find the security key in database
const credentialId = Buffer.from(credential.id, 'base64').toString('base64');
const credentialId = credential.id;
const [securityKey] = await db
.select()
.from(securityKeys)
@@ -653,9 +642,9 @@ export async function verifyAuthentication(
expectedChallenge: challengeData.challenge,
expectedOrigin: origin,
expectedRPID: rpID,
authenticator: {
credentialID: Buffer.from(securityKey.credentialId, 'base64'),
credentialPublicKey: Buffer.from(securityKey.publicKey, 'base64'),
credential: {
id: securityKey.credentialId,
publicKey: isoBase64URL.toBuffer(securityKey.publicKey),
counter: securityKey.signCount,
transports: securityKey.transports ? JSON.parse(securityKey.transports) as AuthenticatorTransportFuture[] : undefined
},
@@ -714,4 +703,4 @@ export async function verifyAuthentication(
)
);
}
}
}

View File

@@ -11,6 +11,7 @@ import m3 from "./scriptsPg/1.8.0";
import m4 from "./scriptsPg/1.9.0";
import m5 from "./scriptsPg/1.10.0";
import m6 from "./scriptsPg/1.10.2";
import m7 from "./scriptsPg/1.10.4";
// THIS CANNOT IMPORT ANYTHING FROM THE SERVER
// EXCEPT FOR THE DATABASE AND THE SCHEMA
@@ -23,6 +24,7 @@ const migrations = [
{ version: "1.9.0", run: m4 },
{ version: "1.10.0", run: m5 },
{ version: "1.10.2", run: m6 },
{ version: "1.10.4", run: m7 },
// Add new migrations here as they are created
] as {
version: string;

View File

@@ -29,6 +29,7 @@ import m24 from "./scriptsSqlite/1.9.0";
import m25 from "./scriptsSqlite/1.10.0";
import m26 from "./scriptsSqlite/1.10.1";
import m27 from "./scriptsSqlite/1.10.2";
import m28 from "./scriptsSqlite/1.10.4";
// THIS CANNOT IMPORT ANYTHING FROM THE SERVER
// EXCEPT FOR THE DATABASE AND THE SCHEMA
@@ -57,6 +58,7 @@ const migrations = [
{ version: "1.10.0", run: m25 },
{ version: "1.10.1", run: m26 },
{ version: "1.10.2", run: m27 },
{ version: "1.10.4", run: m28 },
// Add new migrations here as they are created
] as const;

View File

@@ -0,0 +1,53 @@
import { db } from "@server/db/pg/driver";
import { sql } from "drizzle-orm";
import { isoBase64URL } from "@simplewebauthn/server/helpers";
const version = "1.10.4";
export default async function migration() {
console.log(`Running setup script ${version}...`);
try {
await db.execute(sql`BEGIN`);
const webauthnCredentialsQuery = await db.execute(sql`SELECT "credentialId", "publicKey", "userId", "signCount", "transports", "name", "lastUsed", "dateCreated" FROM "webauthnCredentials"`);
const webauthnCredentials = webauthnCredentialsQuery.rows as {
credentialId: string;
publicKey: string;
userId: string;
signCount: number;
transports: string | null;
name: string | null;
lastUsed: string;
dateCreated: string;
}[];
for (const webauthnCredential of webauthnCredentials) {
const newCredentialId = isoBase64URL.fromBuffer(new Uint8Array(Buffer.from(webauthnCredential.credentialId, 'base64')));
const newPublicKey = isoBase64URL.fromBuffer(new Uint8Array(Buffer.from(webauthnCredential.publicKey, 'base64')));
// Delete the old record
await db.execute(sql`
DELETE FROM "webauthnCredentials"
WHERE "credentialId" = ${webauthnCredential.credentialId}
`);
// Insert the updated record with converted values
await db.execute(sql`
INSERT INTO "webauthnCredentials" ("credentialId", "publicKey", "userId", "signCount", "transports", "name", "lastUsed", "dateCreated")
VALUES (${newCredentialId}, ${newPublicKey}, ${webauthnCredential.userId}, ${webauthnCredential.signCount}, ${webauthnCredential.transports}, ${webauthnCredential.name}, ${webauthnCredential.lastUsed}, ${webauthnCredential.dateCreated})
`);
}
await db.execute(sql`COMMIT`);
console.log(`Updated credentialId and publicKey`);
} catch (e) {
await db.execute(sql`ROLLBACK`);
console.log("Unable to update credentialId and publicKey");
console.log(e);
throw e;
}
console.log(`${version} migration complete`);
}

View File

@@ -0,0 +1,44 @@
import { APP_PATH } from "@server/lib/consts";
import Database from "better-sqlite3";
import path from "path";
import { isoBase64URL } from "@simplewebauthn/server/helpers";
const version = "1.10.4";
export default async function migration() {
console.log(`Running setup script ${version}...`);
const location = path.join(APP_PATH, "db", "db.sqlite");
const db = new Database(location);
db.transaction(() => {
const webauthnCredentials = db.prepare(`SELECT credentialId, publicKey, userId, signCount, transports, name, lastUsed, dateCreated FROM 'webauthnCredentials'`).all() as {
credentialId: string; publicKey: string; userId: string; signCount: number; transports: string | null; name: string | null; lastUsed: string; dateCreated: string;
}[];
for (const webauthnCredential of webauthnCredentials) {
const newCredentialId = isoBase64URL.fromBuffer(new Uint8Array(Buffer.from(webauthnCredential.credentialId, 'base64')));
const newPublicKey = isoBase64URL.fromBuffer(new Uint8Array(Buffer.from(webauthnCredential.publicKey, 'base64')));
// Delete the old record
db.prepare(`DELETE FROM 'webauthnCredentials' WHERE 'credentialId' = ?`).run(webauthnCredential.credentialId);
// Insert the updated record with converted values
db.prepare(
`INSERT INTO 'webauthnCredentials' (credentialId, publicKey, userId, signCount, transports, name, lastUsed, dateCreated) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
).run(
newCredentialId,
newPublicKey,
webauthnCredential.userId,
webauthnCredential.signCount,
webauthnCredential.transports,
webauthnCredential.name,
webauthnCredential.lastUsed,
webauthnCredential.dateCreated
);
}
})();
console.log(`${version} migration complete`);
}

View File

@@ -63,7 +63,7 @@ export default function AccessControlsPage() {
autoProvisioned: z.boolean()
});
const form = useForm<z.infer<typeof formSchema>>({
const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
username: user.username!,

View File

@@ -161,7 +161,7 @@ export default function Page() {
{ hours: 168, name: t("day", { count: 7 }) }
];
const internalForm = useForm<z.infer<typeof internalFormSchema>>({
const internalForm = useForm({
resolver: zodResolver(internalFormSchema),
defaultValues: {
email: "",
@@ -170,7 +170,7 @@ export default function Page() {
}
});
const googleAzureForm = useForm<z.infer<typeof googleAzureFormSchema>>({
const googleAzureForm = useForm({
resolver: zodResolver(googleAzureFormSchema),
defaultValues: {
email: "",
@@ -179,7 +179,7 @@ export default function Page() {
}
});
const genericOidcForm = useForm<z.infer<typeof genericOidcFormSchema>>({
const genericOidcForm = useForm({
resolver: zodResolver(genericOidcFormSchema),
defaultValues: {
username: "",

View File

@@ -91,14 +91,14 @@ export default function Page() {
type CopiedFormValues = z.infer<typeof copiedFormSchema>;
const form = useForm<CreateFormValues>({
const form = useForm({
resolver: zodResolver(createFormSchema),
defaultValues: {
name: ""
}
});
const copiedForm = useForm<CopiedFormValues>({
const copiedForm = useForm({
resolver: zodResolver(copiedFormSchema),
defaultValues: {
copied: true

View File

@@ -58,7 +58,7 @@ export default function GeneralPage() {
const [clientSites, setClientSites] = useState<Tag[]>([]);
const [activeSitesTagIndex, setActiveSitesTagIndex] = useState<number | null>(null);
const form = useForm<GeneralFormValues>({
const form = useForm({
resolver: zodResolver(GeneralFormSchema),
defaultValues: {
name: client?.name,

View File

@@ -150,40 +150,41 @@ export default function Page() {
const commands = {
mac: {
"Apple Silicon (arm64)": [
`curl -L -o olm "https://github.com/fosrl/olm/releases/download/${version}/olm_darwin_arm64" && chmod +x ./olm`,
`sudo ./olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
`curl -fsSL https://digpangolin.com/get-olm.sh | bash`,
`sudo olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
],
"Intel x64 (amd64)": [
`curl -L -o olm "https://github.com/fosrl/olm/releases/download/${version}/olm_darwin_amd64" && chmod +x ./olm`,
`sudo ./olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
`curl -fsSL https://digpangolin.com/get-olm.sh | bash`,
`sudo olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
]
},
linux: {
amd64: [
`wget -O olm "https://github.com/fosrl/olm/releases/download/${version}/olm_linux_amd64" && chmod +x ./olm`,
`sudo ./olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
`curl -fsSL https://digpangolin.com/get-olm.sh | bash`,
`sudo olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
],
arm64: [
`wget -O olm "https://github.com/fosrl/olm/releases/download/${version}/olm_linux_arm64" && chmod +x ./olm`,
`sudo ./olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
`curl -fsSL https://digpangolin.com/get-olm.sh | bash`,
`sudo olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
],
arm32: [
`wget -O olm "https://github.com/fosrl/olm/releases/download/${version}/olm_linux_arm32" && chmod +x ./olm`,
`sudo ./olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
`curl -fsSL https://digpangolin.com/get-olm.sh | bash`,
`sudo olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
],
arm32v6: [
`wget -O olm "https://github.com/fosrl/olm/releases/download/${version}/olm_linux_arm32v6" && chmod +x ./olm`,
`sudo ./olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
`curl -fsSL https://digpangolin.com/get-olm.sh | bash`,
`sudo olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
],
riscv64: [
`wget -O olm "https://github.com/fosrl/olm/releases/download/${version}/olm_linux_riscv64" && chmod +x ./olm`,
`sudo ./olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
`curl -fsSL https://digpangolin.com/get-olm.sh | bash`,
`sudo olm --id ${id} --secret ${secret} --endpoint ${endpoint}`
]
},
windows: {
x64: [
`# Download and run the installer`,
`curl -o olm.exe -L "https://github.com/fosrl/olm/releases/download/${version}/olm_windows_installer.exe"`,
`# Run the installer to install olm and wintun`,
`# Then run olm with your credentials`,
`olm.exe --id ${id} --secret ${secret} --endpoint ${endpoint}`
]
}
@@ -265,7 +266,7 @@ export default function Page() {
}
};
const form = useForm<CreateClientFormValues>({
const form = useForm({
resolver: zodResolver(createClientFormSchema),
defaultValues: {
name: "",

View File

@@ -59,7 +59,7 @@ export default function GeneralPage() {
const [loadingDelete, setLoadingDelete] = useState(false);
const [loadingSave, setLoadingSave] = useState(false);
const form = useForm<GeneralFormValues>({
const form = useForm({
resolver: zodResolver(GeneralFormSchema),
defaultValues: {
name: org?.org.name,

View File

@@ -138,12 +138,12 @@ export default function ResourceAuthenticationPage() {
const [isSetPasswordOpen, setIsSetPasswordOpen] = useState(false);
const [isSetPincodeOpen, setIsSetPincodeOpen] = useState(false);
const usersRolesForm = useForm<z.infer<typeof UsersRolesFormSchema>>({
const usersRolesForm = useForm({
resolver: zodResolver(UsersRolesFormSchema),
defaultValues: { roles: [], users: [] }
});
const whitelistForm = useForm<z.infer<typeof whitelistSchema>>({
const whitelistForm = useForm({
resolver: zodResolver(whitelistSchema),
defaultValues: { emails: [] }
});

View File

@@ -119,7 +119,7 @@ export default function GeneralForm() {
type GeneralFormValues = z.infer<typeof GeneralFormSchema>;
const form = useForm<GeneralFormValues>({
const form = useForm({
resolver: zodResolver(GeneralFormSchema),
defaultValues: {
enabled: resource.enabled,

View File

@@ -260,7 +260,7 @@ export default function ReverseProxyTargets(props: {
port: "" as any as number,
path: null,
pathMatchType: null
} as z.infer<typeof addTargetSchema>
}
});
const watchedIp = addTargetForm.watch("ip");
@@ -274,7 +274,7 @@ export default function ReverseProxyTargets(props: {
}
};
const tlsSettingsForm = useForm<TlsSettingsValues>({
const tlsSettingsForm = useForm({
resolver: zodResolver(tlsSettingsSchema),
defaultValues: {
ssl: resource.ssl,
@@ -282,7 +282,7 @@ export default function ReverseProxyTargets(props: {
}
});
const proxySettingsForm = useForm<ProxySettingsValues>({
const proxySettingsForm = useForm({
resolver: zodResolver(proxySettingsSchema),
defaultValues: {
setHostHeader: resource.setHostHeader || "",
@@ -290,7 +290,7 @@ export default function ReverseProxyTargets(props: {
}
});
const targetsSettingsForm = useForm<TargetsSettingsValues>({
const targetsSettingsForm = useForm({
resolver: zodResolver(targetsSettingsSchema),
defaultValues: {
stickySession: resource.stickySession

View File

@@ -114,7 +114,7 @@ export default function ResourceRules(props: {
CIDR: t('ipAddressRange')
} as const;
const addRuleForm = useForm<z.infer<typeof addRuleSchema>>({
const addRuleForm = useForm({
resolver: zodResolver(addRuleSchema),
defaultValues: {
action: "ACCEPT",

View File

@@ -211,7 +211,7 @@ export default function Page() {
])
];
const baseForm = useForm<BaseResourceFormValues>({
const baseForm = useForm({
resolver: zodResolver(baseResourceFormSchema),
defaultValues: {
name: "",
@@ -219,12 +219,12 @@ export default function Page() {
}
});
const httpForm = useForm<HttpResourceFormValues>({
const httpForm = useForm({
resolver: zodResolver(httpResourceFormSchema),
defaultValues: {}
});
const tcpUdpForm = useForm<TcpUdpResourceFormValues>({
const tcpUdpForm = useForm({
resolver: zodResolver(tcpUdpResourceFormSchema),
defaultValues: {
protocol: "tcp",
@@ -241,7 +241,7 @@ export default function Page() {
port: "" as any as number,
path: null,
pathMatchType: null
} as z.infer<typeof addTargetSchema>
}
});
const watchedIp = addTargetForm.watch("ip");

View File

@@ -64,7 +64,7 @@ export default function GeneralPage() {
const router = useRouter();
const t = useTranslations();
const form = useForm<GeneralFormValues>({
const form = useForm({
resolver: zodResolver(GeneralFormSchema),
defaultValues: {
name: site?.name,

View File

@@ -425,7 +425,7 @@ WantedBy=default.target`
}
};
const form = useForm<CreateSiteFormValues>({
const form = useForm({
resolver: zodResolver(createSiteFormSchema),
defaultValues: {
name: "",

View File

@@ -89,14 +89,14 @@ export default function Page() {
type CopiedFormValues = z.infer<typeof copiedFormSchema>;
const form = useForm<CreateFormValues>({
const form = useForm({
resolver: zodResolver(createFormSchema),
defaultValues: {
name: ""
}
});
const copiedForm = useForm<CopiedFormValues>({
const copiedForm = useForm({
resolver: zodResolver(copiedFormSchema),
defaultValues: {
copied: true

View File

@@ -74,7 +74,7 @@ export default function GeneralPage() {
type GeneralFormValues = z.infer<typeof GeneralFormSchema>;
const form = useForm<GeneralFormValues>({
const form = useForm({
resolver: zodResolver(GeneralFormSchema),
defaultValues: {
name: "",

View File

@@ -102,7 +102,7 @@ export default function PoliciesPage() {
type PolicyFormValues = z.infer<typeof policyFormSchema>;
type DefaultMappingsValues = z.infer<typeof defaultMappingsSchema>;
const form = useForm<PolicyFormValues>({
const form = useForm({
resolver: zodResolver(policyFormSchema),
defaultValues: {
orgId: "",
@@ -111,7 +111,7 @@ export default function PoliciesPage() {
}
});
const defaultMappingsForm = useForm<DefaultMappingsValues>({
const defaultMappingsForm = useForm({
resolver: zodResolver(defaultMappingsSchema),
defaultValues: {
defaultRoleMapping: "",

View File

@@ -79,7 +79,7 @@ export default function Page() {
}
];
const form = useForm<CreateIdpFormValues>({
const form = useForm({
resolver: zodResolver(createIdpFormSchema),
defaultValues: {
name: "",

View File

@@ -97,7 +97,7 @@ export default function LicensePage() {
})
});
const form = useForm<z.infer<typeof formSchema>>({
const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
licenseKey: "",

View File

@@ -51,7 +51,7 @@ export default function InitialSetupPage() {
const [error, setError] = useState<string | null>(null);
const [checking, setChecking] = useState(true);
const form = useForm<z.infer<typeof formSchema>>({
const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
setupToken: "",

View File

@@ -102,7 +102,7 @@ export default function ResetPasswordForm({
code: z.string().length(6, { message: t('pincodeInvalid') })
});
const form = useForm<z.infer<typeof formSchema>>({
const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
email: emailParam || "",
@@ -112,14 +112,14 @@ export default function ResetPasswordForm({
}
});
const mfaForm = useForm<z.infer<typeof mfaSchema>>({
const mfaForm = useForm({
resolver: zodResolver(mfaSchema),
defaultValues: {
code: ""
}
});
const requestForm = useForm<z.infer<typeof requestSchema>>({
const requestForm = useForm({
resolver: zodResolver(requestSchema),
defaultValues: {
email: emailParam || ""

View File

@@ -50,7 +50,7 @@ export default function StepperForm() {
subnet: z.string().min(1, { message: t("subnetRequired") })
});
const orgForm = useForm<z.infer<typeof orgSchema>>({
const orgForm = useForm({
resolver: zodResolver(orgSchema),
defaultValues: {
orgName: "",

View File

@@ -84,7 +84,7 @@ export function IdpCreateWizard({ onSubmit, defaultValues, loading = false }: Id
}
];
const form = useForm<CreateIdpFormValues>({
const form = useForm({
resolver: zodResolver(createIdpFormSchema),
defaultValues: {
name: "",

View File

@@ -90,7 +90,7 @@ export default function LoginForm({ redirect, onLogin, idps }: LoginFormProps) {
code: z.string().length(6, { message: t("pincodeInvalid") })
});
const form = useForm<z.infer<typeof formSchema>>({
const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
email: "",
@@ -98,7 +98,7 @@ export default function LoginForm({ redirect, onLogin, idps }: LoginFormProps) {
}
});
const mfaForm = useForm<z.infer<typeof mfaSchema>>({
const mfaForm = useForm({
resolver: zodResolver(mfaSchema),
defaultValues: {
code: ""

View File

@@ -102,7 +102,7 @@ export default function ResetPasswordForm({
code: z.string().length(6, { message: t('pincodeInvalid') })
});
const form = useForm<z.infer<typeof formSchema>>({
const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
email: emailParam || "",
@@ -112,14 +112,14 @@ export default function ResetPasswordForm({
}
});
const mfaForm = useForm<z.infer<typeof mfaSchema>>({
const mfaForm = useForm({
resolver: zodResolver(mfaSchema),
defaultValues: {
code: ""
}
});
const requestForm = useForm<z.infer<typeof requestSchema>>({
const requestForm = useForm({
resolver: zodResolver(requestSchema),
defaultValues: {
email: emailParam || ""

View File

@@ -141,28 +141,28 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
const [activeTab, setActiveTab] = useState(getDefaultSelectedMethod());
const pinForm = useForm<z.infer<typeof pinSchema>>({
const pinForm = useForm({
resolver: zodResolver(pinSchema),
defaultValues: {
pin: ""
}
});
const passwordForm = useForm<z.infer<typeof passwordSchema>>({
const passwordForm = useForm({
resolver: zodResolver(passwordSchema),
defaultValues: {
password: ""
}
});
const requestOtpForm = useForm<z.infer<typeof requestOtpSchema>>({
const requestOtpForm = useForm({
resolver: zodResolver(requestOtpSchema),
defaultValues: {
email: ""
}
});
const submitOtpForm = useForm<z.infer<typeof submitOtpSchema>>({
const submitOtpForm = useForm({
resolver: zodResolver(submitOtpSchema),
defaultValues: {
email: "",

View File

@@ -119,7 +119,7 @@ export default function SecurityKeyForm({
code: z.string().optional()
});
const registerForm = useForm<RegisterFormValues>({
const registerForm = useForm({
resolver: zodResolver(registerSchema),
defaultValues: {
name: "",
@@ -128,7 +128,7 @@ export default function SecurityKeyForm({
}
});
const deleteForm = useForm<DeleteFormValues>({
const deleteForm = useForm({
resolver: zodResolver(deleteSchema),
defaultValues: {
password: "",

View File

@@ -39,10 +39,6 @@ const setPasswordFormSchema = z.object({
type SetPasswordFormValues = z.infer<typeof setPasswordFormSchema>;
const defaultValues: Partial<SetPasswordFormValues> = {
password: ""
};
type SetPasswordFormProps = {
open: boolean;
setOpen: (open: boolean) => void;
@@ -61,9 +57,11 @@ export default function SetResourcePasswordForm({
const [loading, setLoading] = useState(false);
const form = useForm<SetPasswordFormValues>({
const form = useForm({
resolver: zodResolver(setPasswordFormSchema),
defaultValues
defaultValues: {
password: ""
}
});
useEffect(() => {

View File

@@ -44,10 +44,6 @@ const setPincodeFormSchema = z.object({
type SetPincodeFormValues = z.infer<typeof setPincodeFormSchema>;
const defaultValues: Partial<SetPincodeFormValues> = {
pincode: ""
};
type SetPincodeFormProps = {
open: boolean;
setOpen: (open: boolean) => void;
@@ -65,9 +61,11 @@ export default function SetResourcePincodeForm({
const api = createApiClient(useEnvContext());
const form = useForm<SetPincodeFormValues>({
const form = useForm({
resolver: zodResolver(setPincodeFormSchema),
defaultValues
defaultValues: {
pincode: ""
}
});
const t = useTranslations();

View File

@@ -117,7 +117,7 @@ export default function SignupForm({
const [passwordValue, setPasswordValue] = useState("");
const [confirmPasswordValue, setConfirmPasswordValue] = useState("");
const form = useForm<z.infer<typeof formSchema>>({
const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
email: emailParam || "",

View File

@@ -78,7 +78,7 @@ export default function SupporterStatus({ isCollapsed = false }: SupporterStatus
key: z.string().nonempty({ message: "Supporter key is required" })
});
const form = useForm<z.infer<typeof formSchema>>({
const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
githubUsername: "",

View File

@@ -91,14 +91,14 @@ const TwoFactorSetupForm = forwardRef<
code: z.string().length(6, { message: t("pincodeInvalid") })
});
const enableForm = useForm<z.infer<typeof enableSchema>>({
const enableForm = useForm({
resolver: zodResolver(enableSchema),
defaultValues: {
password: initialPassword || ""
}
});
const confirmForm = useForm<z.infer<typeof confirmSchema>>({
const confirmForm = useForm({
resolver: zodResolver(confirmSchema),
defaultValues: {
code: ""

View File

@@ -80,7 +80,7 @@ export default function VerifyEmailForm({
})
});
const form = useForm<z.infer<typeof FormSchema>>({
const form = useForm({
resolver: zodResolver(FormSchema),
defaultValues: {
email: email,