first commit
This commit is contained in:
commit
2cf2eafe97
11 changed files with 2868 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
node_modules/
|
||||
107
README.md
Normal file
107
README.md
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
# Webauthn server e client
|
||||
|
||||
## Server
|
||||
|
||||
porta configurata 3400
|
||||
|
||||
vai nel folder server e installa con
|
||||
|
||||
npm install
|
||||
|
||||
poi avvia il server
|
||||
|
||||
node server.js
|
||||
|
||||
si avvia su port 3400
|
||||
|
||||
nginx é configurato per funzionare con auth.patachina.it
|
||||
|
||||
```sh
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name auth.patachina.it;
|
||||
|
||||
ssl_certificate ssl/live/patachina.it/fullchain.pem;
|
||||
ssl_certificate_key ssl/live/patachina.it/privkey.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://192.168.1.3:3400;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwar>
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Mantieni le connessioni per sessioni
|
||||
proxy_set_header Connection "";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Client su nginx
|
||||
|
||||
nginx é configurato come my.patachina2.casacam.net
|
||||
|
||||
```sh
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name my.patachina2.casacam.net;
|
||||
|
||||
# Certificati SSL (sostituisci con i tuoi)
|
||||
ssl_certificate ssl/live/patachina2.casacam.net/fullchai>
|
||||
ssl_certificate_key ssl/live/patachina2.casacam.net/priv>
|
||||
|
||||
# Proxy verso il server statico (npx serve)
|
||||
location / {
|
||||
proxy_pass http://192.168.1.3:3000; # npx serve gir>
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwar>
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Mantieni connessioni aperte
|
||||
proxy_set_header Connection "";
|
||||
}
|
||||
|
||||
# Opzionale: sicurezza base
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
}
|
||||
```
|
||||
|
||||
## Client statico
|
||||
|
||||
porta usata 3000
|
||||
|
||||
vai su client-static
|
||||
|
||||
avvia il server con
|
||||
|
||||
npx serve .
|
||||
|
||||
l'applicazione é su https://my.patachina2.casacam.net
|
||||
|
||||
tutto é stato co figurato per la porta 3000 ma poi avviare anche su altra porta es 3001 ma va cambiato anche nginx
|
||||
|
||||
nox serve . -p 3001
|
||||
|
||||
## Client con node+vite
|
||||
|
||||
vai sul folder client-node-vite
|
||||
|
||||
installa
|
||||
|
||||
npm install
|
||||
|
||||
esegui in modalitá dedug con
|
||||
|
||||
npm dev
|
||||
|
||||
altrimenti in produzione prima lo buildi e poi lo avvii
|
||||
|
||||
npm run build
|
||||
npm run preview
|
||||
|
||||
l'applicazione é su https://my.patachina2.casacam.net visto come abbiamo configurato nginx
|
||||
38
client-node-vite/index.html
Normal file
38
client-node-vite/index.html
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>WebAuthn Client</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body class="flex flex-col items-center p-6 font-sans bg-gray-50 min-h-screen">
|
||||
<h1 class="text-3xl font-bold mb-8 text-center">Demo WebAuthn</h1>
|
||||
|
||||
<div class="flex flex-col gap-6 w-full max-w-md">
|
||||
<label for="username" class="font-semibold text-lg">Username:</label>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
value="fabio"
|
||||
class="border rounded px-4 py-3 w-full text-lg focus:outline-none focus:ring-2 focus:ring-blue>"
|
||||
/>
|
||||
|
||||
<button
|
||||
id="registerBtn"
|
||||
class="bg-blue-600 text-white py-3 px-4 rounded-lg hover:bg-blue-700 transition text-lg w-full"
|
||||
>
|
||||
Registrati
|
||||
</button>
|
||||
|
||||
<button
|
||||
id="loginBtn"
|
||||
class="bg-green-600 text-white py-3 px-4 rounded-lg hover:bg-green-700 transition text-lg w-fu>"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script type="module" src="/webauthn-client.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
951
client-node-vite/package-lock.json
generated
Normal file
951
client-node-vite/package-lock.json
generated
Normal file
|
|
@ -0,0 +1,951 @@
|
|||
{
|
||||
"name": "webauthn-client",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "webauthn-client",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@simplewebauthn/browser": "^13.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^5.4.21"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
|
||||
"integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
|
||||
"integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
|
||||
"integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
|
||||
"integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
|
||||
"integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
|
||||
"integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
|
||||
"integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
|
||||
"integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
|
||||
"integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
|
||||
"integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
|
||||
"integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
|
||||
"integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
|
||||
"integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
|
||||
"integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
|
||||
"integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz",
|
||||
"integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz",
|
||||
"integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz",
|
||||
"integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz",
|
||||
"integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz",
|
||||
"integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz",
|
||||
"integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz",
|
||||
"integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz",
|
||||
"integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz",
|
||||
"integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz",
|
||||
"integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz",
|
||||
"integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz",
|
||||
"integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openharmony"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz",
|
||||
"integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz",
|
||||
"integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz",
|
||||
"integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@simplewebauthn/browser": {
|
||||
"version": "13.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.2.2.tgz",
|
||||
"integrity": "sha512-FNW1oLQpTJyqG5kkDg5ZsotvWgmBaC6jCHR7Ej0qUNep36Wl9tj2eZu7J5rP+uhXgHaLk+QQ3lqcw2vS5MX1IA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
||||
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
|
||||
"integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.21.5",
|
||||
"@esbuild/android-arm": "0.21.5",
|
||||
"@esbuild/android-arm64": "0.21.5",
|
||||
"@esbuild/android-x64": "0.21.5",
|
||||
"@esbuild/darwin-arm64": "0.21.5",
|
||||
"@esbuild/darwin-x64": "0.21.5",
|
||||
"@esbuild/freebsd-arm64": "0.21.5",
|
||||
"@esbuild/freebsd-x64": "0.21.5",
|
||||
"@esbuild/linux-arm": "0.21.5",
|
||||
"@esbuild/linux-arm64": "0.21.5",
|
||||
"@esbuild/linux-ia32": "0.21.5",
|
||||
"@esbuild/linux-loong64": "0.21.5",
|
||||
"@esbuild/linux-mips64el": "0.21.5",
|
||||
"@esbuild/linux-ppc64": "0.21.5",
|
||||
"@esbuild/linux-riscv64": "0.21.5",
|
||||
"@esbuild/linux-s390x": "0.21.5",
|
||||
"@esbuild/linux-x64": "0.21.5",
|
||||
"@esbuild/netbsd-x64": "0.21.5",
|
||||
"@esbuild/openbsd-x64": "0.21.5",
|
||||
"@esbuild/sunos-x64": "0.21.5",
|
||||
"@esbuild/win32-arm64": "0.21.5",
|
||||
"@esbuild/win32-ia32": "0.21.5",
|
||||
"@esbuild/win32-x64": "0.21.5"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.6",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
|
||||
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.11",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz",
|
||||
"integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "1.0.8"
|
||||
},
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0",
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.53.3",
|
||||
"@rollup/rollup-android-arm64": "4.53.3",
|
||||
"@rollup/rollup-darwin-arm64": "4.53.3",
|
||||
"@rollup/rollup-darwin-x64": "4.53.3",
|
||||
"@rollup/rollup-freebsd-arm64": "4.53.3",
|
||||
"@rollup/rollup-freebsd-x64": "4.53.3",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.53.3",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.53.3",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.53.3",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.53.3",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-x64-musl": "4.53.3",
|
||||
"@rollup/rollup-openharmony-arm64": "4.53.3",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.53.3",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.53.3",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.53.3",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.53.3",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "5.4.21",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
|
||||
"integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.21.3",
|
||||
"postcss": "^8.4.43",
|
||||
"rollup": "^4.20.0"
|
||||
},
|
||||
"bin": {
|
||||
"vite": "bin/vite.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.0.0 || >=20.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/vitejs/vite?sponsor=1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": "^18.0.0 || >=20.0.0",
|
||||
"less": "*",
|
||||
"lightningcss": "^1.21.0",
|
||||
"sass": "*",
|
||||
"sass-embedded": "*",
|
||||
"stylus": "*",
|
||||
"sugarss": "*",
|
||||
"terser": "^5.4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
},
|
||||
"less": {
|
||||
"optional": true
|
||||
},
|
||||
"lightningcss": {
|
||||
"optional": true
|
||||
},
|
||||
"sass": {
|
||||
"optional": true
|
||||
},
|
||||
"sass-embedded": {
|
||||
"optional": true
|
||||
},
|
||||
"stylus": {
|
||||
"optional": true
|
||||
},
|
||||
"sugarss": {
|
||||
"optional": true
|
||||
},
|
||||
"terser": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
client-node-vite/package.json
Normal file
15
client-node-vite/package.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "webauthn-client",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^5.4.21"
|
||||
},
|
||||
"dependencies": {
|
||||
"@simplewebauthn/browser": "^13.2.2"
|
||||
}
|
||||
}
|
||||
19
client-node-vite/vite.config.js
Normal file
19
client-node-vite/vite.config.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
server: {
|
||||
host: '192.168.1.3',
|
||||
port: 3000,
|
||||
https: false, // WebAuthn richiede HTTPS (usa certificati validi)
|
||||
allowedHosts: ['my.patachina2.casacam.net'],
|
||||
hmr: false,
|
||||
proxy: {
|
||||
// opzionale: se vuoi proxare /webauthn verso auth.patachina.it
|
||||
'/my': {
|
||||
target: 'https://auth.patachina.it',
|
||||
changeOrigin: true,
|
||||
secure: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
90
client-node-vite/webauthn-client.js
Normal file
90
client-node-vite/webauthn-client.js
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import {
|
||||
startRegistration,
|
||||
startAuthentication
|
||||
//} from 'https://cdn.jsdelivr.net/npm/@simplewebauthn/browser/+esm';
|
||||
} from '@simplewebauthn/browser';
|
||||
const API_BASE = 'https://auth.patachina.it';
|
||||
|
||||
function getUsername() {
|
||||
return document.getElementById('username').value.trim();
|
||||
}
|
||||
|
||||
async function registerUser() {
|
||||
try {
|
||||
|
||||
const username = getUsername();
|
||||
|
||||
const resp = await fetch(`${API_BASE}/my/register-options`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
// body: JSON.stringify({ username: 'fabio' }),
|
||||
body: JSON.stringify({ username }),
|
||||
credentials: 'include',
|
||||
});
|
||||
const options = await resp.json();
|
||||
const attResp = await startRegistration(options);
|
||||
console.log('attResp: ',attResp);
|
||||
const payload = {
|
||||
username: 'fabio',
|
||||
attestationResponse: attResp
|
||||
};
|
||||
console.log(payload);
|
||||
const verif = await fetch(`${API_BASE}/my/register-verify`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
credentials: 'include',
|
||||
})
|
||||
const verification = await verif.json();
|
||||
console.log('verification: ', verification);
|
||||
alert(`Registrazione: ${verification.success ? 'OK' : 'Fallita'}`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert('Errore nella registrazione');
|
||||
}
|
||||
}
|
||||
|
||||
async function loginUser() {
|
||||
try {
|
||||
|
||||
const username = getUsername();
|
||||
|
||||
const resp = await fetch(`${API_BASE}/my/login-options`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
/* body: JSON.stringify({
|
||||
username: 'fabio',
|
||||
}, // tutto l’oggetto di risposta
|
||||
), */
|
||||
body: JSON.stringify({ username }),
|
||||
credentials: 'include',
|
||||
});
|
||||
const options = await resp.json();
|
||||
if (!resp.ok) {
|
||||
// Qui uso il campo message inviato dal server
|
||||
throw new Error(options.message || 'Errore sconosciuto');
|
||||
}
|
||||
console.log('options: ',options);
|
||||
const authResp = await startAuthentication(options);
|
||||
console.log('authResp: ',authResp);
|
||||
const verif = await fetch(`${API_BASE}/my/login-verify`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(
|
||||
{username: 'fabio',
|
||||
assertionResponse: authResp}, // tutto l’oggetto di risposta
|
||||
),
|
||||
credentials: 'include',
|
||||
});
|
||||
const verification = await verif.json();
|
||||
console.log('verification: ', verification);
|
||||
//alert(JSON.stringify(verification));
|
||||
alert(`Login: ${verification.success ? 'OK' : 'Fallito'}`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert(`Login fallito: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('registerBtn').addEventListener('click', registerUser);
|
||||
document.getElementById('loginBtn').addEventListener('click', loginUser);
|
||||
130
client-static/index.html
Normal file
130
client-static/index.html
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>WebAuthn Client</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body class="flex flex-col items-center p-6 font-sans bg-gray-50 min-h-screen">
|
||||
<h1 class="text-3xl font-bold mb-8 text-center">Demo WebAuthn</h1>
|
||||
|
||||
<div class="flex flex-col gap-6 w-full max-w-md">
|
||||
<label for="username" class="font-semibold text-lg">Username:</label>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
value="fabio"
|
||||
class="border rounded px-4 py-3 w-full text-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
/>
|
||||
|
||||
<button
|
||||
id="registerBtn"
|
||||
class="bg-blue-600 text-white py-3 px-4 rounded-lg hover:bg-blue-700 transition text-lg w-full"
|
||||
>
|
||||
Registrati
|
||||
</button>
|
||||
|
||||
<button
|
||||
id="loginBtn"
|
||||
class="bg-green-600 text-white py-3 px-4 rounded-lg hover:bg-green-700 transition text-lg w-full"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Script come ES Module -->
|
||||
<script type="module">
|
||||
import {
|
||||
startRegistration,
|
||||
startAuthentication
|
||||
} from 'https://cdn.jsdelivr.net/npm/@simplewebauthn/browser/+esm';
|
||||
|
||||
const API_BASE = 'https://auth.patachina.it';
|
||||
|
||||
function getUsername() {
|
||||
return document.getElementById('username').value.trim();
|
||||
}
|
||||
|
||||
async function registerUser() {
|
||||
try {
|
||||
|
||||
const username = getUsername();
|
||||
|
||||
const resp = await fetch(`${API_BASE}/my/register-options`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
// body: JSON.stringify({ username: 'fabio' }),
|
||||
body: JSON.stringify({ username }),
|
||||
credentials: 'include',
|
||||
});
|
||||
const options = await resp.json();
|
||||
const attResp = await startRegistration(options);
|
||||
console.log('attResp: ',attResp);
|
||||
const payload = {
|
||||
username: 'fabio',
|
||||
attestationResponse: attResp
|
||||
};
|
||||
console.log(payload);
|
||||
const verif = await fetch(`${API_BASE}/my/register-verify`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
credentials: 'include',
|
||||
})
|
||||
const verification = await verif.json();
|
||||
console.log('verification: ', verification);
|
||||
alert(`Registrazione: ${verification.success ? 'OK' : 'Fallita'}`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert('Errore nella registrazione');
|
||||
}
|
||||
}
|
||||
|
||||
async function loginUser() {
|
||||
try {
|
||||
|
||||
const username = getUsername();
|
||||
|
||||
const resp = await fetch(`${API_BASE}/my/login-options`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
/* body: JSON.stringify({
|
||||
username: 'fabio',
|
||||
}, // tutto l’oggetto di risposta
|
||||
), */
|
||||
body: JSON.stringify({ username }),
|
||||
credentials: 'include',
|
||||
});
|
||||
const options = await resp.json();
|
||||
if (!resp.ok) {
|
||||
// Qui uso il campo message inviato dal server
|
||||
throw new Error(options.message || 'Errore sconosciuto');
|
||||
}
|
||||
console.log('options: ',options);
|
||||
const authResp = await startAuthentication(options);
|
||||
console.log('authResp: ',authResp);
|
||||
const verif = await fetch(`${API_BASE}/my/login-verify`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(
|
||||
{username: 'fabio',
|
||||
assertionResponse: authResp}, // tutto l’oggetto di risposta
|
||||
),
|
||||
credentials: 'include',
|
||||
});
|
||||
const verification = await verif.json();
|
||||
console.log('verification: ', verification);
|
||||
//alert(JSON.stringify(verification));
|
||||
alert(`Login: ${verification.success ? 'OK' : 'Fallito'}`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert(`Login fallito: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('registerBtn').addEventListener('click', registerUser);
|
||||
document.getElementById('loginBtn').addEventListener('click', loginUser);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1195
server/package-lock.json
generated
Normal file
1195
server/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
19
server/package.json
Normal file
19
server/package.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "webauthn-s",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@simplewebauthn/server": "^13.2.2",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^5.1.0",
|
||||
"express-session": "^1.18.2",
|
||||
"uuid": "^13.0.0"
|
||||
}
|
||||
}
|
||||
303
server/server.js
Normal file
303
server/server.js
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const { v4: uuidv4 } = require('uuid');
|
||||
const {
|
||||
generateRegistrationOptions,
|
||||
verifyRegistrationResponse,
|
||||
generateAuthenticationOptions,
|
||||
verifyAuthenticationResponse,
|
||||
} = require('@simplewebauthn/server');
|
||||
// CommonJS
|
||||
const { isoBase64URL } = require('@simplewebauthn/server/helpers');
|
||||
const session = require('express-session');
|
||||
|
||||
const app = express();
|
||||
app.set('trust proxy', 1); // dietro NGINX/HTTPS
|
||||
app.use(express.json());
|
||||
|
||||
app.use(session({
|
||||
name: 'sid',
|
||||
secret: process.env.SESSION_SECRET || 'sono1chiave#moltolunga99esicura',
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
cookie: {
|
||||
httpOnly: true,
|
||||
secure: true, // true in produzione con HTTPS
|
||||
sameSite: 'none', // 'none' per cross-site; richiede secure:true
|
||||
maxAge: 24 * 60 * 60 * 1000
|
||||
}
|
||||
}));
|
||||
|
||||
app.use(cors({
|
||||
origin: [
|
||||
'https://app.patachina.it',
|
||||
'https://my.patachina2.casacam.net',
|
||||
'http://localhost:5000'
|
||||
],
|
||||
credentials: true
|
||||
}));
|
||||
|
||||
const rpID = 'my.patachina2.casacam.net'; // Android emulator localhost
|
||||
const origin = `https://${rpID}`;
|
||||
|
||||
const userDB = {}; // In-memory user store
|
||||
const appDB = {};
|
||||
const user1DB = {};
|
||||
const challregDB = {};
|
||||
const challlogDB = {};
|
||||
const uuDB = {};
|
||||
const uidDB = {};
|
||||
function isBase64Url(str) {
|
||||
return typeof str === 'string' && /^[A-Za-z0-9\-_]+$/.test(str);
|
||||
}
|
||||
|
||||
const appMy = {
|
||||
id: 'my',
|
||||
appname: 'my',
|
||||
rpID: 'my.patachina2.casacam.net',
|
||||
rpName: 'my Local Authn service',
|
||||
origin: `https://my.patachina2.casacam.net`,
|
||||
}
|
||||
|
||||
appDB['my'] = appMy;
|
||||
|
||||
app.post('/:appId/register-options', async (req, res) => {
|
||||
try {
|
||||
console.log('start register options');
|
||||
const appId = req.params.appId;
|
||||
const { username } = req.body;
|
||||
|
||||
if (!appId || !username) {
|
||||
throw new Error('Missing appId or username');
|
||||
}
|
||||
|
||||
// Genera un nuovo UUID v4
|
||||
const userIdString = uuidv4();
|
||||
const userId = Buffer.from(userIdString, 'utf8');
|
||||
const userId64 = isoBase64URL.fromBuffer(userId);
|
||||
|
||||
const key = `${username}:${appId}`;
|
||||
uuDB[key] = {
|
||||
id: key,
|
||||
userId: userId64,
|
||||
date: new Date(),
|
||||
};
|
||||
|
||||
uidDB[userId64] = {
|
||||
id: userId64,
|
||||
app: appId,
|
||||
devices: [],
|
||||
};
|
||||
|
||||
const options = await generateRegistrationOptions({
|
||||
rpName: appDB[appId]?.rpName || 'Default RP',
|
||||
rpID: appDB[appId]?.rpID || 'localhost',
|
||||
userID: userId,
|
||||
userName: username,
|
||||
// authenticatorSelection: { userVerification: 'preferred' }
|
||||
});
|
||||
|
||||
uidDB[userId64].challengereg = options.challenge;
|
||||
|
||||
//console.log('options reg: ', options);
|
||||
//console.log('uidDB[userId64]: ', uidDB[userId64]);
|
||||
|
||||
req.session.userID = userId64;
|
||||
//console.log('session reg opt', req.session);
|
||||
console.log('end register options user:', username);
|
||||
res.json(options);
|
||||
} catch (err) {
|
||||
console.error('❌ Error in register-options:', err);
|
||||
|
||||
// Risposta di errore al client
|
||||
res.status(500).json({
|
||||
error: 'Registration options failed',
|
||||
message: err.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/:appId/register-verify', async (req, res) => {
|
||||
try {
|
||||
const { username, attestationResponse } = req.body;
|
||||
console.log('start session reg ver');
|
||||
|
||||
const appId = req.params.appId;
|
||||
const userId64 = req.session.userID;
|
||||
|
||||
if (!userId64 || !uidDB[userId64]) {
|
||||
throw new Error('User session or uidDB entry not found');
|
||||
}
|
||||
|
||||
const uid = uidDB[userId64];
|
||||
//console.log('uid.challengereg: ', uid.challengereg);
|
||||
|
||||
const verification = await verifyRegistrationResponse({
|
||||
response: attestationResponse,
|
||||
expectedChallenge: uid.challengereg,
|
||||
expectedOrigin: appDB[appId]?.origin,
|
||||
expectedRPID: appDB[appId]?.rpID,
|
||||
// requireUserVerification: false,
|
||||
});
|
||||
|
||||
//console.log('verification: ', verification);
|
||||
|
||||
delete uidDB[userId64].challengereg;
|
||||
|
||||
const success = verification.verified;
|
||||
if (success) {
|
||||
uidDB[userId64].devices.push(verification.registrationInfo);
|
||||
//console.log('uidDB[userId64] dopo ver reg: ', uidDB[userId64]);
|
||||
console.log('success true');
|
||||
} else {
|
||||
console.log('success false');
|
||||
}
|
||||
|
||||
// Gestione distruzione sessione con error handling
|
||||
req.session.destroy(err => {
|
||||
if (err) {
|
||||
console.error('❌ Errore cancellazione sessione:', err);
|
||||
return res.status(500).json({ success });
|
||||
}
|
||||
res.clearCookie('sid').json({ success });
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
console.error('❌ Error in register-verify:', err);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Registration verification failed',
|
||||
message: err.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
app.post('/:appId/login-options', async (req, res) => {
|
||||
try {
|
||||
console.log('start session login opt');
|
||||
|
||||
const { username } = req.body;
|
||||
const appId = req.params.appId;
|
||||
|
||||
if (!username || !appId) {
|
||||
throw new Error('Missing username or appId');
|
||||
}
|
||||
|
||||
const key = `${username}:${appId}`;
|
||||
if (!uuDB[key]) {
|
||||
console.log(`Utente ${username} non registrato`);
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
message: `Utente ${username} non registrato`,
|
||||
});
|
||||
}
|
||||
|
||||
const userId64 = uuDB[key].userId;
|
||||
const user = uidDB[userId64];
|
||||
//console.log('xxx devices:', user);
|
||||
|
||||
if (!user || !user.devices || user.devices.length === 0) {
|
||||
return res.status(404).json({ error: 'User not found or no devices registered' });
|
||||
}
|
||||
|
||||
const all = {
|
||||
allowCredentials: user.devices.map(dev => ({
|
||||
id: dev.credential.id, // base64url string
|
||||
type: 'public-key',
|
||||
transports: dev.transports || ['internal', 'hybrid'],
|
||||
})),
|
||||
userVerification: 'discouraged', // oppure 'preferred' / 'required'
|
||||
rpID: appDB[appId]?.rpID || 'localhost',
|
||||
timeout: 60000,
|
||||
};
|
||||
|
||||
const options = await generateAuthenticationOptions(all);
|
||||
|
||||
uidDB[userId64].challengelog = options.challenge;
|
||||
//console.log('uidDB[userId64] ', uidDB[userId64]);
|
||||
console.log('end session logion options username:',username);
|
||||
req.session.userID = userId64;
|
||||
res.json(options);
|
||||
|
||||
} catch (err) {
|
||||
console.error('❌ Error in login-options:', err);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Login options failed',
|
||||
message: err.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/:appId/login-verify', async (req, res) => {
|
||||
try {
|
||||
console.log('start session login verify');
|
||||
const { username, assertionResponse } = req.body;
|
||||
const appId = req.params.appId;
|
||||
const userId64 = req.session.userID;
|
||||
|
||||
if (!userId64 || !uidDB[userId64]) {
|
||||
throw new Error('User session or uidDB entry not found');
|
||||
}
|
||||
|
||||
const user = uidDB[userId64];
|
||||
if (!user || !user.devices || user.devices.length === 0) {
|
||||
throw new Error('No devices registered for this user');
|
||||
}
|
||||
|
||||
let verified = false;
|
||||
let verification;
|
||||
|
||||
for (const device of user.devices) {
|
||||
const verlog = {
|
||||
response: assertionResponse,
|
||||
expectedChallenge: user.challengelog,
|
||||
expectedOrigin: appDB[appId]?.origin,
|
||||
expectedRPID: appDB[appId]?.rpID,
|
||||
credential: device.credential,
|
||||
};
|
||||
|
||||
verification = await verifyAuthenticationResponse(verlog);
|
||||
|
||||
if (verification.verified) {
|
||||
verified = true;
|
||||
// aggiorna il counter del device usato
|
||||
device.counter = verification.authenticationInfo.newCounter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete uidDB[userId64].challengelog;
|
||||
|
||||
// Risposta finale con gestione sessione
|
||||
req.session.destroy(err => {
|
||||
if (err) {
|
||||
console.error('❌ Errore cancellazione sessione:', err);
|
||||
return res.status(500).json({ success: verified });
|
||||
}
|
||||
|
||||
if (verified) {
|
||||
//console.log('uidDB[userId64] dopo ver log: ', uidDB[userId64]);
|
||||
console.log('success true');
|
||||
return res.clearCookie('sid').json({ success: true });
|
||||
} else {
|
||||
console.log('success false');
|
||||
return res.clearCookie('sid').status(401).json({ success: false });
|
||||
}
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
console.error('❌ Error in login-verify:', err);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Login verification failed',
|
||||
message: err.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
app.listen(3400, '192.168.1.3', () => {
|
||||
console.log('WebAuthn server running on http://192.168.1.3:3400');
|
||||
});
|
||||
Loading…
Reference in a new issue