Compare commits
15 commits
24eb27a949
...
f4fd7403cc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4fd7403cc | ||
|
|
87217f9a3f | ||
|
|
ff5387b778 | ||
|
|
919315bbf7 | ||
|
|
919beb941c | ||
|
|
032b67632e | ||
|
|
70ce3b544d | ||
|
|
dcb9b6695c | ||
|
|
717306a108 |
||
|
|
cbb6c66804 |
||
|
|
6caf570866 |
||
|
|
5b37032ec1 | ||
|
|
109cb5d972 | ||
|
|
e796307f30 | ||
|
|
7d3e7394ed |
13 changed files with 242 additions and 97 deletions
61
.github/workflows/docker-image.yml
vendored
Normal file
61
.github/workflows/docker-image.yml
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
name: Docker image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
|
tags:
|
||||||
|
- 'v*.*.*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
IMAGE_NAME: ${{ github.repository }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push-image:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Log in to the Container registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
tags: |
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=semver,pattern={{major}}
|
||||||
|
type=ref,event=branch
|
||||||
|
type=ref,event=pr
|
||||||
|
type=sha
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -7,3 +7,5 @@ nsecbunker.json
|
||||||
connection.txt
|
connection.txt
|
||||||
config
|
config
|
||||||
.env
|
.env
|
||||||
|
.turbo
|
||||||
|
prisma
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,13 @@
|
||||||
"importOrderSeparation": true,
|
"importOrderSeparation": true,
|
||||||
"tabWidth": 4,
|
"tabWidth": 4,
|
||||||
"useTabs": false,
|
"useTabs": false,
|
||||||
"semi": true
|
"semi": true,
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": "*.handlebar",
|
||||||
|
"options": {
|
||||||
|
"tabWidth": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "nsecbunkerd",
|
"name": "nsecbunkerd",
|
||||||
"version": "0.10.3",
|
"version": "0.10.5",
|
||||||
"description": "nsecbunker daemon",
|
"description": "nsecbunker daemon",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
"@fastify/view": "^8.2.0",
|
"@fastify/view": "^8.2.0",
|
||||||
"@inquirer/password": "^1.1.2",
|
"@inquirer/password": "^1.1.2",
|
||||||
"@inquirer/prompts": "^1.2.3",
|
"@inquirer/prompts": "^1.2.3",
|
||||||
"@nostr-dev-kit/ndk": "^2.4.2",
|
"@nostr-dev-kit/ndk": "workspace:*",
|
||||||
"@prisma/client": "^5.4.1",
|
"@prisma/client": "^5.4.1",
|
||||||
"@scure/base": "^1.1.1",
|
"@scure/base": "^1.1.1",
|
||||||
"@types/yargs": "^17.0.24",
|
"@types/yargs": "^17.0.24",
|
||||||
|
|
|
||||||
85
pnpm-lock.yaml
generated
85
pnpm-lock.yaml
generated
|
|
@ -18,8 +18,8 @@ dependencies:
|
||||||
specifier: ^1.2.3
|
specifier: ^1.2.3
|
||||||
version: 1.2.3
|
version: 1.2.3
|
||||||
'@nostr-dev-kit/ndk':
|
'@nostr-dev-kit/ndk':
|
||||||
specifier: ^2.4.2
|
specifier: ^2.8.1
|
||||||
version: 2.4.2(typescript@5.1.3)
|
version: 2.8.1(typescript@5.1.3)
|
||||||
'@prisma/client':
|
'@prisma/client':
|
||||||
specifier: ^5.4.1
|
specifier: ^5.4.1
|
||||||
version: 5.4.1(prisma@5.4.1)
|
version: 5.4.1(prisma@5.4.1)
|
||||||
|
|
@ -46,10 +46,10 @@ dependencies:
|
||||||
version: 16.3.1
|
version: 16.3.1
|
||||||
eslint-config-prettier:
|
eslint-config-prettier:
|
||||||
specifier: ^8.8.0
|
specifier: ^8.8.0
|
||||||
version: 8.8.0(eslint@8.56.0)
|
version: 8.8.0(eslint@8.57.0)
|
||||||
eslint-plugin-import:
|
eslint-plugin-import:
|
||||||
specifier: ^2.27.5
|
specifier: ^2.27.5
|
||||||
version: 2.27.5(eslint@8.56.0)
|
version: 2.27.5(eslint@8.57.0)
|
||||||
eventemitter3:
|
eventemitter3:
|
||||||
specifier: ^5.0.1
|
specifier: ^5.0.1
|
||||||
version: 5.0.1
|
version: 5.0.1
|
||||||
|
|
@ -316,13 +316,13 @@ packages:
|
||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@eslint-community/eslint-utils@4.4.0(eslint@8.56.0):
|
/@eslint-community/eslint-utils@4.4.0(eslint@8.57.0):
|
||||||
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
|
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
|
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.56.0
|
eslint: 8.57.0
|
||||||
eslint-visitor-keys: 3.4.3
|
eslint-visitor-keys: 3.4.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
|
@ -348,8 +348,8 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@eslint/js@8.56.0:
|
/@eslint/js@8.57.0:
|
||||||
resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==}
|
resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
|
@ -393,7 +393,7 @@ packages:
|
||||||
resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
|
resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
|
||||||
engines: {node: '>=10.10.0'}
|
engines: {node: '>=10.10.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@humanwhocodes/object-schema': 2.0.2
|
'@humanwhocodes/object-schema': 2.0.3
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
minimatch: 3.1.2
|
minimatch: 3.1.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
|
@ -405,8 +405,8 @@ packages:
|
||||||
engines: {node: '>=12.22'}
|
engines: {node: '>=12.22'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@humanwhocodes/object-schema@2.0.2:
|
/@humanwhocodes/object-schema@2.0.3:
|
||||||
resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==}
|
resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@inquirer/checkbox@1.3.2:
|
/@inquirer/checkbox@1.3.2:
|
||||||
|
|
@ -599,6 +599,12 @@ packages:
|
||||||
'@noble/hashes': 1.3.1
|
'@noble/hashes': 1.3.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@noble/curves@1.4.0:
|
||||||
|
resolution: {integrity: sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==}
|
||||||
|
dependencies:
|
||||||
|
'@noble/hashes': 1.4.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@noble/hashes@1.3.1:
|
/@noble/hashes@1.3.1:
|
||||||
resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==}
|
resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==}
|
||||||
engines: {node: '>= 16'}
|
engines: {node: '>= 16'}
|
||||||
|
|
@ -609,13 +615,13 @@ packages:
|
||||||
engines: {node: '>= 16'}
|
engines: {node: '>= 16'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@noble/hashes@1.3.3:
|
/@noble/hashes@1.4.0:
|
||||||
resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==}
|
resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==}
|
||||||
engines: {node: '>= 16'}
|
engines: {node: '>= 16'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@noble/secp256k1@2.0.0:
|
/@noble/secp256k1@2.1.0:
|
||||||
resolution: {integrity: sha512-rUGBd95e2a45rlmFTqQJYEFA4/gdIARFfuTuTqLglz0PZ6AKyzyXsEZZq7UZn8hZsvaBgpCzKKBJizT2cJERXw==}
|
resolution: {integrity: sha512-XLEQQNdablO0XZOIniFQimiXsZDNwaYgL96dZwC54Q30imSbAOFf3NKtepc+cXyuZf5Q1HCgbqgZ2UFFuHVcEw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@nodelib/fs.scandir@2.1.5:
|
/@nodelib/fs.scandir@2.1.5:
|
||||||
|
|
@ -636,14 +642,15 @@ packages:
|
||||||
'@nodelib/fs.scandir': 2.1.5
|
'@nodelib/fs.scandir': 2.1.5
|
||||||
fastq: 1.15.0
|
fastq: 1.15.0
|
||||||
|
|
||||||
/@nostr-dev-kit/ndk@2.4.2(typescript@5.1.3):
|
/@nostr-dev-kit/ndk@2.8.1(typescript@5.1.3):
|
||||||
resolution: {integrity: sha512-78gHKyPVy2u6obnTmOU9dMJMi07LgzoTQtO1RjWkcwlQvPyjbpCQ4EXjDSM1pmdj7narwW+uJibnld6z8dT1Fg==}
|
resolution: {integrity: sha512-2WPN1FVhxcLxFYwva2Ti6XKQUjqU0jfdoHHhqDF+0Mxp8f/uDyLflsUQCXsZym5rOIHY85eCYhAXi6V6q6gpRg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@noble/hashes': 1.3.3
|
'@noble/curves': 1.4.0
|
||||||
'@noble/secp256k1': 2.0.0
|
'@noble/hashes': 1.4.0
|
||||||
|
'@noble/secp256k1': 2.1.0
|
||||||
'@scure/base': 1.1.1
|
'@scure/base': 1.1.1
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
light-bolt11-decoder: 3.0.0
|
light-bolt11-decoder: 3.1.1
|
||||||
node-fetch: 3.3.2
|
node-fetch: 3.3.2
|
||||||
nostr-tools: 1.17.0(typescript@5.1.3)
|
nostr-tools: 1.17.0(typescript@5.1.3)
|
||||||
tseep: 1.2.1
|
tseep: 1.2.1
|
||||||
|
|
@ -1464,13 +1471,13 @@ packages:
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/eslint-config-prettier@8.8.0(eslint@8.56.0):
|
/eslint-config-prettier@8.8.0(eslint@8.57.0):
|
||||||
resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==}
|
resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: '>=7.0.0'
|
eslint: '>=7.0.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.56.0
|
eslint: 8.57.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/eslint-import-resolver-node@0.3.7:
|
/eslint-import-resolver-node@0.3.7:
|
||||||
|
|
@ -1483,7 +1490,7 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/eslint-module-utils@2.8.0(eslint-import-resolver-node@0.3.7)(eslint@8.56.0):
|
/eslint-module-utils@2.8.0(eslint-import-resolver-node@0.3.7)(eslint@8.57.0):
|
||||||
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
|
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -1505,13 +1512,13 @@ packages:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 3.2.7
|
debug: 3.2.7
|
||||||
eslint: 8.56.0
|
eslint: 8.57.0
|
||||||
eslint-import-resolver-node: 0.3.7
|
eslint-import-resolver-node: 0.3.7
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/eslint-plugin-import@2.27.5(eslint@8.56.0):
|
/eslint-plugin-import@2.27.5(eslint@8.57.0):
|
||||||
resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==}
|
resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -1526,9 +1533,9 @@ packages:
|
||||||
array.prototype.flatmap: 1.3.1
|
array.prototype.flatmap: 1.3.1
|
||||||
debug: 3.2.7
|
debug: 3.2.7
|
||||||
doctrine: 2.1.0
|
doctrine: 2.1.0
|
||||||
eslint: 8.56.0
|
eslint: 8.57.0
|
||||||
eslint-import-resolver-node: 0.3.7
|
eslint-import-resolver-node: 0.3.7
|
||||||
eslint-module-utils: 2.8.0(eslint-import-resolver-node@0.3.7)(eslint@8.56.0)
|
eslint-module-utils: 2.8.0(eslint-import-resolver-node@0.3.7)(eslint@8.57.0)
|
||||||
has: 1.0.3
|
has: 1.0.3
|
||||||
is-core-module: 2.12.1
|
is-core-module: 2.12.1
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
|
|
@ -1556,15 +1563,15 @@ packages:
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/eslint@8.56.0:
|
/eslint@8.57.0:
|
||||||
resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==}
|
resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
|
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
|
||||||
'@eslint-community/regexpp': 4.10.0
|
'@eslint-community/regexpp': 4.10.0
|
||||||
'@eslint/eslintrc': 2.1.4
|
'@eslint/eslintrc': 2.1.4
|
||||||
'@eslint/js': 8.56.0
|
'@eslint/js': 8.57.0
|
||||||
'@humanwhocodes/config-array': 0.11.14
|
'@humanwhocodes/config-array': 0.11.14
|
||||||
'@humanwhocodes/module-importer': 1.0.1
|
'@humanwhocodes/module-importer': 1.0.1
|
||||||
'@nodelib/fs.walk': 1.2.8
|
'@nodelib/fs.walk': 1.2.8
|
||||||
|
|
@ -1819,7 +1826,7 @@ packages:
|
||||||
engines: {node: ^12.20 || >= 14.13}
|
engines: {node: ^12.20 || >= 14.13}
|
||||||
dependencies:
|
dependencies:
|
||||||
node-domexception: 1.0.0
|
node-domexception: 1.0.0
|
||||||
web-streams-polyfill: 3.3.2
|
web-streams-polyfill: 3.3.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/figures@3.2.0:
|
/figures@3.2.0:
|
||||||
|
|
@ -1879,13 +1886,13 @@ packages:
|
||||||
resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
|
resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
dependencies:
|
dependencies:
|
||||||
flatted: 3.2.9
|
flatted: 3.3.1
|
||||||
keyv: 4.5.4
|
keyv: 4.5.4
|
||||||
rimraf: 3.0.2
|
rimraf: 3.0.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/flatted@3.2.9:
|
/flatted@3.3.1:
|
||||||
resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
|
resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/follow-redirects@1.15.3(debug@4.3.4):
|
/follow-redirects@1.15.3(debug@4.3.4):
|
||||||
|
|
@ -2429,8 +2436,8 @@ packages:
|
||||||
type-check: 0.4.0
|
type-check: 0.4.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/light-bolt11-decoder@3.0.0:
|
/light-bolt11-decoder@3.1.1:
|
||||||
resolution: {integrity: sha512-AKvOigD2pmC8ktnn2TIqdJu0K0qk6ukUmTvHwF3JNkm8uWCqt18Ijn33A/a7gaRZ4PghJ59X+8+MXrzLKdBTmQ==}
|
resolution: {integrity: sha512-sLg/KCwYkgsHWkefWd6KqpCHrLFWWaXTOX3cf6yD2hAzL0SLpX+lFcaFK2spkjbgzG6hhijKfORDc9WoUHwX0A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@scure/base': 1.1.1
|
'@scure/base': 1.1.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
@ -3593,8 +3600,8 @@ packages:
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/web-streams-polyfill@3.3.2:
|
/web-streams-polyfill@3.3.3:
|
||||||
resolution: {integrity: sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==}
|
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
|
|
||||||
22
scripts/start.ts
Normal file
22
scripts/start.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { execSync, spawn } from "child_process";
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log(`Running migrations`);
|
||||||
|
// check if config folder exists
|
||||||
|
if (!fs.existsSync('./config')) {
|
||||||
|
execSync(`mkdir config`);
|
||||||
|
}
|
||||||
|
execSync('npm run prisma:migrate');
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
// Handle any potential migration errors here
|
||||||
|
}
|
||||||
|
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
const childProcess = spawn('node', ['./dist/index.js', ...args], {
|
||||||
|
stdio: 'inherit',
|
||||||
|
});
|
||||||
|
|
||||||
|
childProcess.on('exit', (code) => {
|
||||||
|
process.exit(code);
|
||||||
|
});
|
||||||
|
|
@ -76,6 +76,8 @@ function loadPrivateKey(): string | undefined {
|
||||||
(async () => {
|
(async () => {
|
||||||
let remoteUser: NDKUser;
|
let remoteUser: NDKUser;
|
||||||
|
|
||||||
|
ndk = await createNDK();
|
||||||
|
|
||||||
// if this is the create_account command and we have something that doesn't look like an npub as the remotePubkey, use NDKUser.fromNip05 to get the npub
|
// if this is the create_account command and we have something that doesn't look like an npub as the remotePubkey, use NDKUser.fromNip05 to get the npub
|
||||||
if (command === 'create_account' && !remotePubkey.startsWith("npub")) {
|
if (command === 'create_account' && !remotePubkey.startsWith("npub")) {
|
||||||
// see if we have a username@domain
|
// see if we have a username@domain
|
||||||
|
|
@ -88,7 +90,7 @@ function loadPrivateKey(): string | undefined {
|
||||||
|
|
||||||
content = `${username},${domain}`
|
content = `${username},${domain}`
|
||||||
|
|
||||||
const u = await NDKUser.fromNip05(domain);
|
const u = await NDKUser.fromNip05(domain, ndk);
|
||||||
if (!u) {
|
if (!u) {
|
||||||
console.log(`Invalid nip05 ${remotePubkey}`);
|
console.log(`Invalid nip05 ${remotePubkey}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
|
@ -110,7 +112,7 @@ function loadPrivateKey(): string | undefined {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk = await createNDK();
|
|
||||||
let localSigner: NDKPrivateKeySigner;
|
let localSigner: NDKPrivateKeySigner;
|
||||||
|
|
||||||
const pk = loadPrivateKey();
|
const pk = loadPrivateKey();
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,10 @@ async function nip89announcement(configData: IConfig) {
|
||||||
const relays = config.nip89!.relays;
|
const relays = config.nip89!.relays;
|
||||||
const nip05 = `_@${domain}`;
|
const nip05 = `_@${domain}`;
|
||||||
|
|
||||||
|
const ndk = new NDK({explicitRelayUrls: relays});
|
||||||
|
|
||||||
// make sure the nip05 correctly points to this pubkey
|
// make sure the nip05 correctly points to this pubkey
|
||||||
const uservianip05 = await NDKUser.fromNip05(nip05);
|
const uservianip05 = await NDKUser.fromNip05(nip05, ndk);
|
||||||
if (!uservianip05 || uservianip05.pubkey !== signerUser.pubkey) {
|
if (!uservianip05 || uservianip05.pubkey !== signerUser.pubkey) {
|
||||||
console.log(`❌ ${nip05} does not point to this nsecbunker's key`);
|
console.log(`❌ ${nip05} does not point to this nsecbunker's key`);
|
||||||
if (uservianip05) {
|
if (uservianip05) {
|
||||||
|
|
@ -53,7 +55,6 @@ async function nip89announcement(configData: IConfig) {
|
||||||
const hasWallet = !!config.wallet;
|
const hasWallet = !!config.wallet;
|
||||||
const hasNostrdress = !!config.wallet?.lnbits?.nostdressUrl;
|
const hasNostrdress = !!config.wallet?.lnbits?.nostdressUrl;
|
||||||
|
|
||||||
const ndk = new NDK({explicitRelayUrls: relays});
|
|
||||||
ndk.signer = signer;
|
ndk.signer = signer;
|
||||||
ndk.connect(5000).then(async () => {
|
ndk.connect(5000).then(async () => {
|
||||||
const event = new NDKAppHandlerEvent(ndk, {
|
const event = new NDKAppHandlerEvent(ndk, {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import "websocket-polyfill";
|
import "websocket-polyfill";
|
||||||
import NDK, { NDKKind, NDKPrivateKeySigner, NDKRpcRequest, NDKRpcResponse, NDKUser } from '@nostr-dev-kit/ndk';
|
import NDK, { NDKEvent, NDKKind, NDKPrivateKeySigner, NDKRpcRequest, NDKRpcResponse, NDKUser, NostrEvent } from '@nostr-dev-kit/ndk';
|
||||||
import { NDKNostrRpc } from '@nostr-dev-kit/ndk';
|
import { NDKNostrRpc } from '@nostr-dev-kit/ndk';
|
||||||
import createDebug from 'debug';
|
import createDebug from 'debug';
|
||||||
import { Key, KeyUser } from '../run';
|
import { Key, KeyUser } from '../run';
|
||||||
|
|
@ -121,6 +121,8 @@ class AdminInterface {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.rpc.on('request', (req) => this.handleRequest(req));
|
this.rpc.on('request', (req) => this.handleRequest(req));
|
||||||
|
|
||||||
|
pingOrDie(this.ndk);
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log('❌ admin connection failed');
|
console.log('❌ admin connection failed');
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
|
@ -393,4 +395,44 @@ class AdminInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function pingOrDie(ndk: NDK) {
|
||||||
|
let deathTimer: NodeJS.Timeout | null = null;
|
||||||
|
|
||||||
|
function resetDeath() {
|
||||||
|
if (deathTimer) clearTimeout(deathTimer);
|
||||||
|
deathTimer = setTimeout(() => {
|
||||||
|
console.log(`❌ No ping event received in 30 seconds. Exiting.`);
|
||||||
|
process.exit(1);
|
||||||
|
}, 50000);
|
||||||
|
}
|
||||||
|
|
||||||
|
const self = await ndk.signer!.user();
|
||||||
|
const sub = ndk.subscribe({
|
||||||
|
authors: [self.pubkey],
|
||||||
|
kinds: [NDKKind.NostrConnect],
|
||||||
|
"#p": [self.pubkey]
|
||||||
|
});
|
||||||
|
sub.on("event", (event: NDKEvent) => {
|
||||||
|
console.log(`🔔 Received ping event:`, event.created_at);
|
||||||
|
resetDeath();
|
||||||
|
});
|
||||||
|
sub.start();
|
||||||
|
|
||||||
|
resetDeath();
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
const event = new NDKEvent(ndk, {
|
||||||
|
kind: NDKKind.NostrConnect,
|
||||||
|
tags: [ ["p", self.pubkey] ],
|
||||||
|
content: "ping"
|
||||||
|
} as NostrEvent);
|
||||||
|
event.publish().then(() => {
|
||||||
|
console.log(`🔔 Sent ping event:`, event.created_at);
|
||||||
|
}).catch((e: any) => {
|
||||||
|
console.log(`❌ Failed to send ping event:`, e.message);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
}, 20000);
|
||||||
|
}
|
||||||
|
|
||||||
export default AdminInterface;
|
export default AdminInterface;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import NDK, { NDKNip46Backend, Nip46PermitCallback } from '@nostr-dev-kit/ndk';
|
import NDK, { NDKNip46Backend, NDKPrivateKeySigner, Nip46PermitCallback } from '@nostr-dev-kit/ndk';
|
||||||
import prisma from '../../db.js';
|
import prisma from '../../db.js';
|
||||||
import type {FastifyInstance} from "fastify";
|
import type {FastifyInstance} from "fastify";
|
||||||
|
|
||||||
|
|
@ -13,7 +13,8 @@ export class Backend extends NDKNip46Backend {
|
||||||
cb: Nip46PermitCallback,
|
cb: Nip46PermitCallback,
|
||||||
baseUrl?: string
|
baseUrl?: string
|
||||||
) {
|
) {
|
||||||
super(ndk, key, cb);
|
const signer = new NDKPrivateKeySigner(key);
|
||||||
|
super(ndk, signer, cb);
|
||||||
|
|
||||||
this.baseUrl = baseUrl;
|
this.baseUrl = baseUrl;
|
||||||
this.fastify = fastify;
|
this.fastify = fastify;
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,20 @@ class Daemon {
|
||||||
*/
|
*/
|
||||||
async startKey(name: string, nsec: string) {
|
async startKey(name: string, nsec: string) {
|
||||||
const cb = signingAuthorizationCallback(name, this.adminInterface);
|
const cb = signingAuthorizationCallback(name, this.adminInterface);
|
||||||
const hexpk = nip19.decode(nsec).data as string;
|
let hexpk: string;
|
||||||
|
|
||||||
|
if (nsec.startsWith('nsec1')) {
|
||||||
|
try {
|
||||||
|
const key = new NDKPrivateKeySigner(nsec);
|
||||||
|
hexpk = key.privateKey!;
|
||||||
|
} catch(e) {
|
||||||
|
console.error(`Error loading key ${name}:`, e);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hexpk = nsec;
|
||||||
|
}
|
||||||
|
|
||||||
const backend = new Backend(this.ndk, this.fastify, hexpk, cb, this.config.baseUrl);
|
const backend = new Backend(this.ndk, this.fastify, hexpk, cb, this.config.baseUrl);
|
||||||
await backend.start();
|
await backend.start();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta name="robots" content="noindex">
|
<meta name="robots" content="noindex" />
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<title>Authorize Request</title>
|
<title>Authorize Request</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<script src="https://cdn.tailwindcss.com?plugins=forms"></script>
|
<script src="https://cdn.tailwindcss.com?plugins=forms"></script>
|
||||||
|
|
@ -75,11 +75,12 @@
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif,
|
||||||
|
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||||
}
|
}
|
||||||
|
|
||||||
.border {
|
.border {
|
||||||
|
|
@ -88,34 +89,42 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
class="flex flex-col justify-center items-center min-h-screen bg-gray-100 dark:bg-neutral-800 text-neutrla-950 dark:text-neutral-50">
|
class="flex flex-col justify-center items-center min-h-screen bg-gray-100 dark:bg-neutral-800 text-neutrla-950 dark:text-neutral-50"
|
||||||
|
>
|
||||||
<div class="max-w-md mx-auto w-full px-2 md:px-4 lg:px-8">
|
<div class="max-w-md mx-auto w-full px-2 md:px-4 lg:px-8">
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<h1
|
<h1
|
||||||
class="text-neutral-950 dark:text-neutral-50 text-lg font-semibold w-full">
|
class="text-neutral-950 dark:text-neutral-50 text-lg font-semibold w-full"
|
||||||
|
>
|
||||||
Do you want to allow this client to use account
|
Do you want to allow this client to use account
|
||||||
<br />
|
<br />
|
||||||
<span class="text-blue-500">{{record.keyName}}</span>?
|
<span class="text-blue-500">{{ record.keyName }}</span
|
||||||
|
>?
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div id="error"
|
<div
|
||||||
class="flex flex-col gap-4 bg-red-200 rounded-lg p-4 w-full hidden">
|
id="error"
|
||||||
</div>
|
class="flex flex-col gap-4 bg-red-200 rounded-lg p-4 w-full hidden"
|
||||||
|
></div>
|
||||||
|
|
||||||
{{#unless authenticated}}
|
{{#unless authenticated}}
|
||||||
<div class="flex flex-col gap-4 mt-10">
|
<div class="flex flex-col gap-4 mt-10">
|
||||||
<label class="flex flex-col gap-2">
|
<label class="flex flex-col gap-2">
|
||||||
<span
|
<span
|
||||||
class="text-sm font-medium text-neutral-800 dark:text-neutral-200">
|
class="text-sm font-medium text-neutral-800 dark:text-neutral-200"
|
||||||
|
>
|
||||||
Enter your password to authenticate this request
|
Enter your password to authenticate this request
|
||||||
</span>
|
</span>
|
||||||
<div
|
<div
|
||||||
class="relative before:pointer-events-none focus-within:before:opacity-100 before:opacity-0 before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-blue-500 before:ring-2 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight dark:after:shadow-white/5 dark:focus-within:after:shadow-blue-500/20 after:transition">
|
class="relative before:pointer-events-none focus-within:before:opacity-100 before:opacity-0 before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-blue-500 before:ring-2 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight dark:after:shadow-white/5 dark:focus-within:after:shadow-blue-500/20 after:transition"
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
name="password"
|
name="password"
|
||||||
|
id="password"
|
||||||
required
|
required
|
||||||
class="w-full relative text-sm text-neutral-800 dark:text-neutral-200 bg-white dark:bg-neutral-750 placeholder:text-neutral-400 dark:placeholder:text-neutral-500 px-3.5 py-2 rounded-lg border border-black/5 shadow-input shadow-black/5 dark:shadow-black/10 !outline-none" />
|
class="w-full relative text-sm text-neutral-800 dark:text-neutral-200 bg-white dark:bg-neutral-750 placeholder:text-neutral-400 dark:placeholder:text-neutral-500 px-3.5 py-2 rounded-lg border border-black/5 shadow-input shadow-black/5 dark:shadow-black/10 !outline-none"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -124,12 +133,14 @@
|
||||||
<div class="flex flex-col items-center justify-center gap-2 mt-5">
|
<div class="flex flex-col items-center justify-center gap-2 mt-5">
|
||||||
<button
|
<button
|
||||||
onclick="sendPostRequest()"
|
onclick="sendPostRequest()"
|
||||||
class="px-6 w-full h-9 bg-neutral-900 dark:bg-neutral-100 hover:bg-neutral-800 dark:hover:bg-neutral-200 dark:text-neutral-950 rounded-lg justify-center items-center gap-2 inline-flex text-white text-sm font-semibold">
|
class="px-6 w-full h-9 bg-neutral-900 dark:bg-neutral-100 hover:bg-neutral-800 dark:hover:bg-neutral-200 dark:text-neutral-950 rounded-lg justify-center items-center gap-2 inline-flex text-white text-sm font-semibold"
|
||||||
|
>
|
||||||
Yes
|
Yes
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onclick="window.close()"
|
onclick="window.close()"
|
||||||
class="px-6 h-9 w-full border border-neutral-300 dark:border-neutral-600 dark:text-neutral-50 rounded-lg justify-center items-center gap-2 inline-flex text-neutral-950 text-sm font-semibold">
|
class="px-6 h-9 w-full border border-neutral-300 dark:border-neutral-600 dark:text-neutral-50 rounded-lg justify-center items-center gap-2 inline-flex text-neutral-950 text-sm font-semibold"
|
||||||
|
>
|
||||||
No
|
No
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -146,7 +157,7 @@
|
||||||
|
|
||||||
<!-- List all cookies -->
|
<!-- List all cookies -->
|
||||||
<script>
|
<script>
|
||||||
const cookies = document.cookie.split(';');
|
const cookies = document.cookie.split(";");
|
||||||
for (let i = 0; i < cookies.length; i++) {
|
for (let i = 0; i < cookies.length; i++) {
|
||||||
console.log(cookies[i]);
|
console.log(cookies[i]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
const form = document.querySelector('form');
|
const form = document.querySelector('form');
|
||||||
const email = document.querySelector('input[name="email"]');
|
|
||||||
const password = document.querySelector('input[name="password"]');
|
const password = document.querySelector('input[name="password"]');
|
||||||
const confirmPassword = document.querySelector('input[name="confirm_password"]');
|
const confirmPassword = document.querySelector('input[name="confirm_password"]');
|
||||||
|
|
||||||
|
|
@ -52,15 +51,6 @@
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if email is valid or empty
|
|
||||||
if (email.value) {
|
|
||||||
const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
|
|
||||||
if (!emailRegex.test(email.value)) {
|
|
||||||
alert("Please enter a valid email address or leave it empty!");
|
|
||||||
valid = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
@ -98,21 +88,7 @@
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<label class="flex flex-col gap-2">
|
<input type="hidden" name="email" value="" />
|
||||||
<span
|
|
||||||
class="text-sm font-medium text-neutral-800 dark:text-neutral-200">
|
|
||||||
Recovery Email
|
|
||||||
</span>
|
|
||||||
<div
|
|
||||||
class="relative before:pointer-events-none focus-within:before:opacity-100 before:opacity-0 before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-blue-500 before:ring-2 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight dark:after:shadow-white/5 dark:focus-within:after:shadow-blue-500/20 after:transition">
|
|
||||||
<input
|
|
||||||
readonly="true"
|
|
||||||
type="email"
|
|
||||||
name="email"
|
|
||||||
value="{{email}}"
|
|
||||||
class="w-full relative text-sm text-blue-500 dark:text-blue-500 bg-neutral-200 dark:bg-neutral-800 placeholder:text-neutral-400 dark:placeholder:text-neutral-500 px-3.5 py-2 rounded-lg border-none" />
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label class="flex flex-col gap-2">
|
<label class="flex flex-col gap-2">
|
||||||
<span
|
<span
|
||||||
|
|
@ -122,7 +98,6 @@
|
||||||
<div
|
<div
|
||||||
class="relative before:pointer-events-none focus-within:before:opacity-100 before:opacity-0 before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-blue-500 before:ring-2 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight dark:after:shadow-white/5 dark:focus-within:after:shadow-blue-500/20 after:transition">
|
class="relative before:pointer-events-none focus-within:before:opacity-100 before:opacity-0 before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-blue-500 before:ring-2 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight dark:after:shadow-white/5 dark:focus-within:after:shadow-blue-500/20 after:transition">
|
||||||
<input
|
<input
|
||||||
readonly="true"
|
|
||||||
type="text"
|
type="text"
|
||||||
name="username"
|
name="username"
|
||||||
value="{{username}}"
|
value="{{username}}"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue