Merge branch 'main' into diagon-alley
This commit is contained in:
commit
627914abda
17 changed files with 134 additions and 52 deletions
15
.github/workflows/migrations.yml
vendored
15
.github/workflows/migrations.yml
vendored
|
|
@ -9,9 +9,9 @@ jobs:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:latest
|
image: postgres:latest
|
||||||
env:
|
env:
|
||||||
POSTGRES_USER: postgres
|
POSTGRES_USER: lnbits
|
||||||
POSTGRES_PASSWORD: postgres
|
POSTGRES_PASSWORD: lnbits
|
||||||
POSTGRES_DB: postgres
|
POSTGRES_DB: migration
|
||||||
ports:
|
ports:
|
||||||
# maps tcp port 5432 on service container to the host
|
# maps tcp port 5432 on service container to the host
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
|
|
@ -36,11 +36,4 @@ jobs:
|
||||||
sudo apt install unzip
|
sudo apt install unzip
|
||||||
- name: Run migrations
|
- name: Run migrations
|
||||||
run: |
|
run: |
|
||||||
rm -rf ./data
|
make test-migration
|
||||||
mkdir -p ./data
|
|
||||||
export LNBITS_DATA_FOLDER="./data"
|
|
||||||
unzip tests/data/mock_data.zip -d ./data
|
|
||||||
timeout 5s poetry run lnbits --host 0.0.0.0 --port 5001 || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; fi
|
|
||||||
export LNBITS_DATABASE_URL="postgres://postgres:postgres@0.0.0.0:5432/postgres"
|
|
||||||
timeout 5s poetry run lnbits --host 0.0.0.0 --port 5001 || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; fi
|
|
||||||
poetry run python tools/conv.py
|
|
||||||
|
|
|
||||||
24
Makefile
24
Makefile
|
|
@ -4,7 +4,7 @@ all: format check requirements.txt
|
||||||
|
|
||||||
format: prettier isort black
|
format: prettier isort black
|
||||||
|
|
||||||
check: mypy checkprettier checkisort checkblack
|
check: mypy checkprettier checkisort checkblack
|
||||||
|
|
||||||
prettier: $(shell find lnbits -name "*.js" -name ".html")
|
prettier: $(shell find lnbits -name "*.js" -name ".html")
|
||||||
./node_modules/.bin/prettier --write lnbits/static/js/*.js lnbits/core/static/js/*.js lnbits/extensions/*/templates/*/*.html ./lnbits/core/templates/core/*.html lnbits/templates/*.html lnbits/extensions/*/static/js/*.js lnbits/extensions/*/static/components/*/*.js lnbits/extensions/*/static/components/*/*.html
|
./node_modules/.bin/prettier --write lnbits/static/js/*.js lnbits/core/static/js/*.js lnbits/extensions/*/templates/*/*.html ./lnbits/core/templates/core/*.html lnbits/templates/*.html lnbits/extensions/*/static/js/*.js lnbits/extensions/*/static/components/*/*.js lnbits/extensions/*/static/components/*/*.html
|
||||||
|
|
@ -32,11 +32,13 @@ test:
|
||||||
FAKE_WALLET_SECRET="ToTheMoon1" \
|
FAKE_WALLET_SECRET="ToTheMoon1" \
|
||||||
LNBITS_DATA_FOLDER="./tests/data" \
|
LNBITS_DATA_FOLDER="./tests/data" \
|
||||||
PYTHONUNBUFFERED=1 \
|
PYTHONUNBUFFERED=1 \
|
||||||
|
DEBUG=true \
|
||||||
poetry run pytest
|
poetry run pytest
|
||||||
|
|
||||||
test-real-wallet:
|
test-real-wallet:
|
||||||
LNBITS_DATA_FOLDER="./tests/data" \
|
LNBITS_DATA_FOLDER="./tests/data" \
|
||||||
PYTHONUNBUFFERED=1 \
|
PYTHONUNBUFFERED=1 \
|
||||||
|
DEBUG=true \
|
||||||
poetry run pytest
|
poetry run pytest
|
||||||
|
|
||||||
test-venv:
|
test-venv:
|
||||||
|
|
@ -44,7 +46,27 @@ test-venv:
|
||||||
FAKE_WALLET_SECRET="ToTheMoon1" \
|
FAKE_WALLET_SECRET="ToTheMoon1" \
|
||||||
LNBITS_DATA_FOLDER="./tests/data" \
|
LNBITS_DATA_FOLDER="./tests/data" \
|
||||||
PYTHONUNBUFFERED=1 \
|
PYTHONUNBUFFERED=1 \
|
||||||
|
DEBUG=true \
|
||||||
./venv/bin/pytest --durations=1 -s --cov=lnbits --cov-report=xml tests
|
./venv/bin/pytest --durations=1 -s --cov=lnbits --cov-report=xml tests
|
||||||
|
|
||||||
|
test-migration:
|
||||||
|
rm -rf ./migration-data
|
||||||
|
mkdir -p ./migration-data
|
||||||
|
unzip tests/data/mock_data.zip -d ./migration-data
|
||||||
|
HOST=0.0.0.0 \
|
||||||
|
PORT=5002 \
|
||||||
|
LNBITS_DATA_FOLDER="./migration-data" \
|
||||||
|
timeout 5s poetry run lnbits --host 0.0.0.0 --port 5002 || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; fi
|
||||||
|
HOST=0.0.0.0 \
|
||||||
|
PORT=5002 \
|
||||||
|
LNBITS_DATABASE_URL="postgres://lnbits:lnbits@localhost:5432/migration" \
|
||||||
|
timeout 5s poetry run lnbits --host 0.0.0.0 --port 5002 || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; fi
|
||||||
|
LNBITS_DATA_FOLDER="./migration-data" \
|
||||||
|
LNBITS_DATABASE_URL="postgres://lnbits:lnbits@localhost:5432/migration" \
|
||||||
|
poetry run python tools/conv.py
|
||||||
|
|
||||||
|
migration:
|
||||||
|
poetry run python tools/conv.py
|
||||||
|
|
||||||
bak:
|
bak:
|
||||||
# LNBITS_DATABASE_URL=postgres://postgres:postgres@0.0.0.0:5432/postgres
|
# LNBITS_DATABASE_URL=postgres://postgres:postgres@0.0.0.0:5432/postgres
|
||||||
|
|
|
||||||
|
|
@ -48,4 +48,25 @@ LNbits currently supports SQLite and PostgreSQL databases. There is a migration
|
||||||
|
|
||||||
### Adding mock data to `mock_data.zip`
|
### Adding mock data to `mock_data.zip`
|
||||||
|
|
||||||
`mock_data.zip` contains a few lines of sample SQLite data and is used in automated GitHub test to see whether your migration in `conv.py` works. Run your extension and save a few lines of data into a SQLite `your_extension.sqlite3` file. Unzip `tests/data/mock_data.zip`, add `your_extension.sqlite3` and zip it again. Add the updated `mock_data.zip` to your PR.
|
`mock_data.zip` contains a few lines of sample SQLite data and is used in automated GitHub test to see whether your migration in `conv.py` works. Run your extension and save a few lines of data into a SQLite `your_extension.sqlite3` file. Unzip `tests/data/mock_data.zip`, add `your_extension.sqlite3`, updated `database.sqlite3` and zip it again. Add the updated `mock_data.zip` to your PR.
|
||||||
|
|
||||||
|
### running migration locally
|
||||||
|
you will need a running postgres database
|
||||||
|
|
||||||
|
#### create lnbits user for migration database
|
||||||
|
```console
|
||||||
|
sudo su - postgres -c "psql -c 'CREATE ROLE lnbits LOGIN PASSWORD 'lnbits';'"
|
||||||
|
```
|
||||||
|
#### create migration database
|
||||||
|
```console
|
||||||
|
sudo su - postgres -c "psql -c 'CREATE DATABASE migration;'"
|
||||||
|
```
|
||||||
|
#### run the migration
|
||||||
|
```console
|
||||||
|
make test-migration
|
||||||
|
```
|
||||||
|
sudo su - postgres -c "psql -c 'CREATE ROLE lnbits LOGIN PASSWORD 'lnbits';'"
|
||||||
|
#### clean migration database afterwards, fails if you try again
|
||||||
|
```console
|
||||||
|
sudo su - postgres -c "psql -c 'DROP DATABASE IF EXISTS migration;'"
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -170,8 +170,9 @@ LNBITS_DATABASE_URL="postgres://postgres:postgres@localhost/lnbits"
|
||||||
|
|
||||||
# START LNbits
|
# START LNbits
|
||||||
# STOP LNbits
|
# STOP LNbits
|
||||||
# on the LNBits folder, locate and edit 'tools/conv.py' with the relevant credentials
|
poetry run python tools/conv.py
|
||||||
python3 tools/conv.py
|
# or
|
||||||
|
make migration
|
||||||
```
|
```
|
||||||
|
|
||||||
Hopefully, everything works and get migrated... Launch LNbits again and check if everything is working properly.
|
Hopefully, everything works and get migrated... Launch LNbits again and check if everything is working properly.
|
||||||
|
|
@ -194,15 +195,14 @@ Description=LNbits
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
# replace with the absolute path of your lnbits installation
|
# replace with the absolute path of your lnbits installation
|
||||||
WorkingDirectory=/home/bitcoin/lnbits
|
WorkingDirectory=/home/lnbits/lnbits-legend
|
||||||
# same here
|
# same here. run `which poetry` if you can't find the poetry binary
|
||||||
ExecStart=/home/bitcoin/lnbits/venv/bin/uvicorn lnbits.__main__:app --port 5000
|
ExecStart=/home/lnbits/.local/bin/poetry run lnbits
|
||||||
# replace with the user that you're running lnbits on
|
# replace with the user that you're running lnbits on
|
||||||
User=bitcoin
|
User=lnbits
|
||||||
Restart=always
|
Restart=always
|
||||||
TimeoutSec=120
|
TimeoutSec=120
|
||||||
RestartSec=30
|
RestartSec=30
|
||||||
# this makes sure that you receive logs in real time
|
|
||||||
Environment=PYTHONUNBUFFERED=1
|
Environment=PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
|
|
||||||
|
|
@ -668,7 +668,17 @@ new Vue({
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
exportCSV: function () {
|
exportCSV: function () {
|
||||||
LNbits.utils.exportCSV(this.paymentsTable.columns, this.payments)
|
// status is important for export but it is not in paymentsTable
|
||||||
|
// because it is manually added with payment detail link and icons
|
||||||
|
// and would cause duplication in the list
|
||||||
|
let columns = this.paymentsTable.columns
|
||||||
|
columns.unshift({
|
||||||
|
name: 'pending',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Pending',
|
||||||
|
field: 'pending'
|
||||||
|
})
|
||||||
|
LNbits.utils.exportCSV(columns, this.payments)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import binascii
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
from binascii import unhexlify
|
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Dict, List, Optional, Tuple, Union
|
from typing import Dict, List, Optional, Tuple, Union
|
||||||
|
|
@ -152,11 +152,23 @@ class CreateInvoiceData(BaseModel):
|
||||||
|
|
||||||
async def api_payments_create_invoice(data: CreateInvoiceData, wallet: Wallet):
|
async def api_payments_create_invoice(data: CreateInvoiceData, wallet: Wallet):
|
||||||
if data.description_hash:
|
if data.description_hash:
|
||||||
description_hash = unhexlify(data.description_hash)
|
try:
|
||||||
|
description_hash = binascii.unhexlify(data.description_hash)
|
||||||
|
except binascii.Error:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.BAD_REQUEST,
|
||||||
|
detail="'description_hash' must be a valid hex string",
|
||||||
|
)
|
||||||
unhashed_description = b""
|
unhashed_description = b""
|
||||||
memo = ""
|
memo = ""
|
||||||
elif data.unhashed_description:
|
elif data.unhashed_description:
|
||||||
unhashed_description = unhexlify(data.unhashed_description)
|
try:
|
||||||
|
unhashed_description = binascii.unhexlify(data.unhashed_description)
|
||||||
|
except binascii.Error:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.BAD_REQUEST,
|
||||||
|
detail="'unhashed_description' must be a valid hex string",
|
||||||
|
)
|
||||||
description_hash = b""
|
description_hash = b""
|
||||||
memo = ""
|
memo = ""
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -130,10 +130,13 @@ async def get_key_type(
|
||||||
# 2: invalid
|
# 2: invalid
|
||||||
pathname = r["path"].split("/")[1]
|
pathname = r["path"].split("/")[1]
|
||||||
|
|
||||||
if not api_key_header and not api_key_query:
|
token = api_key_header or api_key_query
|
||||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
token = api_key_header if api_key_header else api_key_query
|
if not token:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.UNAUTHORIZED,
|
||||||
|
detail="Invoice (or Admin) key required.",
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
admin_checker = WalletAdminKeyChecker(api_key=token)
|
admin_checker = WalletAdminKeyChecker(api_key=token)
|
||||||
|
|
@ -180,7 +183,14 @@ async def require_admin_key(
|
||||||
api_key_header: str = Security(api_key_header), # type: ignore
|
api_key_header: str = Security(api_key_header), # type: ignore
|
||||||
api_key_query: str = Security(api_key_query), # type: ignore
|
api_key_query: str = Security(api_key_query), # type: ignore
|
||||||
):
|
):
|
||||||
token = api_key_header if api_key_header else api_key_query
|
|
||||||
|
token = api_key_header or api_key_query
|
||||||
|
|
||||||
|
if not token:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.UNAUTHORIZED,
|
||||||
|
detail="Admin key required.",
|
||||||
|
)
|
||||||
|
|
||||||
wallet = await get_key_type(r, token)
|
wallet = await get_key_type(r, token)
|
||||||
|
|
||||||
|
|
@ -199,11 +209,12 @@ async def require_invoice_key(
|
||||||
api_key_header: str = Security(api_key_header), # type: ignore
|
api_key_header: str = Security(api_key_header), # type: ignore
|
||||||
api_key_query: str = Security(api_key_query), # type: ignore
|
api_key_query: str = Security(api_key_query), # type: ignore
|
||||||
):
|
):
|
||||||
|
|
||||||
token = api_key_header or api_key_query
|
token = api_key_header or api_key_query
|
||||||
|
|
||||||
if token is None:
|
if not token:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=HTTPStatus.UNAUTHORIZED,
|
||||||
detail="Invoice (or Admin) key required.",
|
detail="Invoice (or Admin) key required.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
Charge people for using your domain name...<br />
|
Charge people for using your domain name...<br />
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="https://github.com/lnbits/lnbits/tree/master/lnbits/extensions/lnaddress"
|
href="https://github.com/lnbits/lnbits-legend/tree/main/lnbits/extensions/lnaddress"
|
||||||
>More details</a
|
>More details</a
|
||||||
>
|
>
|
||||||
<br />
|
<br />
|
||||||
|
|
|
||||||
|
|
@ -296,16 +296,17 @@
|
||||||
<q-btn
|
<q-btn
|
||||||
outline
|
outline
|
||||||
color="grey"
|
color="grey"
|
||||||
|
icon="link"
|
||||||
@click="copyText(qrCodeDialog.data.pay_url, 'Link copied to clipboard!')"
|
@click="copyText(qrCodeDialog.data.pay_url, 'Link copied to clipboard!')"
|
||||||
>Shareable link</q-btn
|
><q-tooltip>Copy sharable link</q-tooltip>
|
||||||
>
|
</q-btn>
|
||||||
<q-btn
|
<q-btn
|
||||||
outline
|
outline
|
||||||
color="grey"
|
color="grey"
|
||||||
icon="nfc"
|
icon="nfc"
|
||||||
@click="writeNfcTag(qrCodeDialog.data.lnurl)"
|
@click="writeNfcTag(qrCodeDialog.data.lnurl)"
|
||||||
:disable="nfcTagWriting"
|
:disable="nfcTagWriting"
|
||||||
>
|
><q-tooltip>Write to NFC</q-tooltip>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
<q-btn
|
<q-btn
|
||||||
outline
|
outline
|
||||||
|
|
@ -314,7 +315,8 @@
|
||||||
type="a"
|
type="a"
|
||||||
:href="qrCodeDialog.data.print_url"
|
:href="qrCodeDialog.data.print_url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
></q-btn>
|
><q-tooltip>Print</q-tooltip></q-btn
|
||||||
|
>
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
|
||||||
|
|
@ -232,7 +232,7 @@
|
||||||
<q-btn
|
<q-btn
|
||||||
outline
|
outline
|
||||||
color="grey"
|
color="grey"
|
||||||
icon="share"
|
icon="link"
|
||||||
@click="copyText(qrCodeDialog.data.pay_url, 'Link copied to clipboard!')"
|
@click="copyText(qrCodeDialog.data.pay_url, 'Link copied to clipboard!')"
|
||||||
><q-tooltip>Copy shareable link</q-tooltip></q-btn
|
><q-tooltip>Copy shareable link</q-tooltip></q-btn
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
Charge people for using your subdomain name...<br />
|
Charge people for using your subdomain name...<br />
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="https://github.com/lnbits/lnbits/tree/master/lnbits/extensions/subdomains"
|
href="https://github.com/lnbits/lnbits-legend/tree/main/lnbits/extensions/subdomains"
|
||||||
>More details</a
|
>More details</a
|
||||||
>
|
>
|
||||||
<br />
|
<br />
|
||||||
|
|
|
||||||
|
|
@ -76,10 +76,10 @@ async def get_tipjars(wallet_id: str) -> Optional[list]:
|
||||||
|
|
||||||
async def delete_tipjar(tipjar_id: int) -> None:
|
async def delete_tipjar(tipjar_id: int) -> None:
|
||||||
"""Delete a TipJar and all corresponding Tips"""
|
"""Delete a TipJar and all corresponding Tips"""
|
||||||
await db.execute("DELETE FROM tipjar.TipJars WHERE id = ?", (tipjar_id,))
|
|
||||||
rows = await db.fetchall("SELECT * FROM tipjar.Tips WHERE tipjar = ?", (tipjar_id,))
|
rows = await db.fetchall("SELECT * FROM tipjar.Tips WHERE tipjar = ?", (tipjar_id,))
|
||||||
for row in rows:
|
for row in rows:
|
||||||
await delete_tip(row["id"])
|
await delete_tip(row["id"])
|
||||||
|
await db.execute("DELETE FROM tipjar.TipJars WHERE id = ?", (tipjar_id,))
|
||||||
|
|
||||||
|
|
||||||
async def get_tip(tip_id: str) -> Optional[Tip]:
|
async def get_tip(tip_id: str) -> Optional[Tip]:
|
||||||
|
|
|
||||||
|
|
@ -418,16 +418,18 @@
|
||||||
<q-btn
|
<q-btn
|
||||||
outline
|
outline
|
||||||
color="grey"
|
color="grey"
|
||||||
|
icon="link"
|
||||||
@click="copyText(qrCodeDialog.data.withdraw_url, 'Link copied to clipboard!')"
|
@click="copyText(qrCodeDialog.data.withdraw_url, 'Link copied to clipboard!')"
|
||||||
>Shareable link</q-btn
|
><q-tooltip>Copy sharable link</q-tooltip>
|
||||||
>
|
</q-btn>
|
||||||
<q-btn
|
<q-btn
|
||||||
outline
|
outline
|
||||||
color="grey"
|
color="grey"
|
||||||
icon="nfc"
|
icon="nfc"
|
||||||
@click="writeNfcTag(qrCodeDialog.data.lnurl)"
|
@click="writeNfcTag(qrCodeDialog.data.lnurl)"
|
||||||
:disable="nfcTagWriting"
|
:disable="nfcTagWriting"
|
||||||
></q-btn>
|
><q-tooltip>Write to NFC</q-tooltip></q-btn
|
||||||
|
>
|
||||||
<q-btn
|
<q-btn
|
||||||
outline
|
outline
|
||||||
color="grey"
|
color="grey"
|
||||||
|
|
@ -435,7 +437,8 @@
|
||||||
type="a"
|
type="a"
|
||||||
:href="qrCodeDialog.data.print_url"
|
:href="qrCodeDialog.data.print_url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
></q-btn>
|
><q-tooltip>Print</q-tooltip></q-btn
|
||||||
|
>
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,11 @@ Vue.component('lnbits-extension-list', {
|
||||||
|
|
||||||
Vue.component('lnbits-payment-details', {
|
Vue.component('lnbits-payment-details', {
|
||||||
props: ['payment'],
|
props: ['payment'],
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
LNBITS_DENOMINATION: LNBITS_DENOMINATION
|
||||||
|
}
|
||||||
|
},
|
||||||
template: `
|
template: `
|
||||||
<div class="q-py-md" style="text-align: left">
|
<div class="q-py-md" style="text-align: left">
|
||||||
<div class="row justify-center q-mb-md">
|
<div class="row justify-center q-mb-md">
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,16 @@ async def test_get_wallet_adminkey(client, adminkey_headers_to):
|
||||||
assert "id" in result
|
assert "id" in result
|
||||||
|
|
||||||
|
|
||||||
# check POST /api/v1/payments: empty request
|
# check PUT /api/v1/wallet/newwallet: empty request where admin key is needed
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_post_empty_request(client):
|
async def test_put_empty_request_expected_admin_keys(client):
|
||||||
|
response = await client.put("/api/v1/wallet/newwallet")
|
||||||
|
assert response.status_code == 401
|
||||||
|
|
||||||
|
|
||||||
|
# check POST /api/v1/payments: empty request where invoice key is needed
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_post_empty_request_expected_invoice_keys(client):
|
||||||
response = await client.post("/api/v1/payments")
|
response = await client.post("/api/v1/payments")
|
||||||
assert response.status_code == 401
|
assert response.status_code == 401
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -19,16 +19,12 @@ env.read_env()
|
||||||
# Change these values as needed
|
# Change these values as needed
|
||||||
|
|
||||||
|
|
||||||
sqfolder = "data/"
|
sqfolder = env.str("LNBITS_DATA_FOLDER", default=None)
|
||||||
|
|
||||||
LNBITS_DATABASE_URL = env.str("LNBITS_DATABASE_URL", default=None)
|
LNBITS_DATABASE_URL = env.str("LNBITS_DATABASE_URL", default=None)
|
||||||
if LNBITS_DATABASE_URL is None:
|
if LNBITS_DATABASE_URL is None:
|
||||||
pgdb = "lnbits"
|
print("missing LNBITS_DATABASE_URL")
|
||||||
pguser = "lnbits"
|
sys.exit(1)
|
||||||
pgpswd = "postgres"
|
|
||||||
pghost = "localhost"
|
|
||||||
pgport = "5432"
|
|
||||||
pgschema = ""
|
|
||||||
else:
|
else:
|
||||||
# parse postgres://lnbits:postgres@localhost:5432/lnbits
|
# parse postgres://lnbits:postgres@localhost:5432/lnbits
|
||||||
pgdb = LNBITS_DATABASE_URL.split("/")[-1]
|
pgdb = LNBITS_DATABASE_URL.split("/")[-1]
|
||||||
|
|
@ -129,7 +125,7 @@ def migrate_db(file: str, schema: str, exclude_tables: List[str] = []):
|
||||||
sq = get_sqlite_cursor(file)
|
sq = get_sqlite_cursor(file)
|
||||||
tables = sq.execute(
|
tables = sq.execute(
|
||||||
"""
|
"""
|
||||||
SELECT name FROM sqlite_master
|
SELECT name FROM sqlite_master
|
||||||
WHERE type='table' AND name not like 'sqlite?_%' escape '?'
|
WHERE type='table' AND name not like 'sqlite?_%' escape '?'
|
||||||
"""
|
"""
|
||||||
).fetchall()
|
).fetchall()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue