Skip to content

Commit c3182c3

Browse files
committed
chore: merge latest upstream/main and update coveralls action
2 parents 8d2c6f9 + f53a471 commit c3182c3

63 files changed

Lines changed: 2909 additions & 690 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/checks.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ jobs:
8686
name: unit-coverage-lcov
8787
path: .coverage/unit/lcov.info
8888
- name: Coveralls
89-
uses: coverallsapp/github-action@master
89+
uses: coverallsapp/github-action@v2
9090
if: ${{ always() }}
9191
with:
9292
path-to-lcov: ./.coverage/unit/lcov.info
@@ -118,7 +118,7 @@ jobs:
118118
- name: Run coverage for integration tests
119119
run: npm run docker:cover:integration
120120
- name: Coveralls
121-
uses: coverallsapp/github-action@master
121+
uses: coverallsapp/github-action@v2
122122
if: ${{ always() }}
123123
with:
124124
path-to-lcov: .coverage/integration/lcov.info
@@ -138,7 +138,7 @@ jobs:
138138
if: ${{ always() }}
139139
steps:
140140
- name: Coveralls Finished
141-
uses: coverallsapp/github-action@master
141+
uses: coverallsapp/github-action@v2
142142
with:
143143
github-token: ${{ secrets.GITHUB_TOKEN }}
144144
parallel-finished: true

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,6 @@ dist
4343
.nostr
4444

4545
# Docker Compose overrides
46-
docker-compose.overrides.yml
46+
docker-compose.overrides.yml
47+
# Export output
48+
*.jsonl

.nycrc.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
{
22
"all": true,
33
"cache": true,
4-
"branches": 80,
5-
"lines": 80,
6-
"functions": 80,
7-
"statements": 80,
4+
"branches": 47,
5+
"lines": 54,
6+
"functions": 48,
7+
"statements": 55,
88
"watermarks": {
99
"lines": [
10-
80,
11-
95
10+
54,
11+
80
1212
],
1313
"functions": [
14-
80,
15-
95
14+
48,
15+
80
1616
],
1717
"branches": [
18-
80,
19-
95
18+
47,
19+
80
2020
],
2121
"statements": [
22-
80,
23-
95
22+
55,
23+
80
2424
]
2525
},
2626
"extension": [

CONFIGURATION.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,10 @@ Running `nostream` for the first time creates the settings file in `<project_roo
119119
| limits.message.ipWhitelist | List of IPs (IPv4 or IPv6) to ignore rate limits. |
120120
| limits.admissionCheck.rateLimits[].period | Rate limit period in milliseconds. |
121121
| limits.admissionCheck.rateLimits[].rate | Maximum number of admission checks during period. |
122-
| limits.admissionCheck.ipWhitelist | List of IPs (IPv4 or IPv6) to ignore rate limits. |
122+
| limits.admissionCheck.ipWhitelist | List of IPs (IPv4 or IPv6) to ignore rate limits. |
123+
| nip05.mode | NIP-05 verification mode: `enabled` requires verification, `passive` verifies without blocking, `disabled` does nothing. Defaults to `disabled`. |
124+
| nip05.verifyExpiration | Time in milliseconds before a successful NIP-05 verification expires and needs re-checking. Defaults to 604800000 (1 week). |
125+
| nip05.verifyUpdateFrequency | Minimum interval in milliseconds between re-verification attempts for a given author. Defaults to 86400000 (24 hours). |
126+
| nip05.maxConsecutiveFailures | Number of consecutive verification failures before giving up on an author. Defaults to 20. |
127+
| nip05.domainWhitelist | List of domains allowed for NIP-05 verification. If set, only authors verified at these domains can publish. |
128+
| nip05.domainBlacklist | List of domains blocked from NIP-05 verification. Authors with NIP-05 at these domains will be rejected. |

README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,53 @@ To observe client and subscription counts in real-time during a test, you can in
614614
```bash
615615
docker compose logs -f nostream
616616
```
617+
## Export Events
618+
619+
Export all stored events to a [JSON Lines](https://jsonlines.org/) (`.jsonl`) file. Each line is a valid NIP-01 Nostr event JSON object. The export streams rows from the database using cursors, so it works safely on relays with millions of events without loading them into memory.
620+
621+
```
622+
npm run export # writes to events.jsonl
623+
npm run export -- backup-2024-01-01.jsonl # custom filename
624+
```
625+
626+
The script reads the same `DB_*` environment variables used by the relay (see [CONFIGURATION.md](CONFIGURATION.md)).
627+
## Relay Maintenance
628+
629+
Use `clean-db` to wipe or prune `events` table data. This also removes
630+
corresponding data from the derived `event_tags` table when present.
631+
632+
Dry run (no deletion):
633+
634+
```
635+
npm run clean-db -- --all --dry-run
636+
```
637+
638+
Full wipe:
639+
640+
```
641+
npm run clean-db -- --all --force
642+
```
643+
644+
Delete events older than N days:
645+
646+
```
647+
npm run clean-db -- --older-than=30 --force
648+
```
649+
650+
Delete only selected kinds:
651+
652+
```
653+
npm run clean-db -- --kinds=1,7,4 --force
654+
```
655+
656+
Delete only selected kinds older than N days:
657+
658+
```
659+
npm run clean-db -- --older-than=30 --kinds=1,7,4 --force
660+
```
661+
662+
By default, the script asks for explicit confirmation (`Type 'DELETE' to confirm`).
663+
Use `--force` to skip the prompt.
617664

618665
## Configuration
619666

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
exports.up = async function (knex) {
2+
return knex.schema
3+
.raw(
4+
`CREATE OR REPLACE FUNCTION admit_user(user_pubkey BYTEA, tos_accepted TIMESTAMP WITHOUT TIME ZONE)
5+
RETURNS INTEGER
6+
LANGUAGE plpgsql
7+
AS $$
8+
BEGIN
9+
PERFORM ASSERT_SERIALIZED();
10+
11+
INSERT INTO "users" ("pubkey", "is_admitted", "tos_accepted_at", "created_at", "updated_at")
12+
VALUES (user_pubkey, true, tos_accepted, now_utc(), now_utc())
13+
ON CONFLICT ("pubkey")
14+
DO UPDATE SET
15+
"is_admitted" = true,
16+
"tos_accepted_at" = tos_accepted,
17+
"updated_at" = now_utc();
18+
19+
RETURN 0;
20+
END;
21+
$$;`)
22+
}
23+
24+
exports.down = function (knex) {
25+
return knex.schema
26+
.raw('DROP FUNCTION IF EXISTS admit_user(BYTEA, TIMESTAMP WITHOUT TIME ZONE);')
27+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
exports.up = function (knex) {
2+
return knex.schema.createTable('nip05_verifications', function (table) {
3+
table.binary('pubkey').notNullable().primary()
4+
table.text('nip05').notNullable()
5+
table.text('domain').notNullable()
6+
table.boolean('is_verified').notNullable().defaultTo(false)
7+
table.timestamp('last_verified_at', { useTz: true }).nullable()
8+
table.timestamp('last_checked_at', { useTz: true }).notNullable().defaultTo(knex.fn.now())
9+
table.integer('failure_count').notNullable().defaultTo(0)
10+
table.timestamp('created_at', { useTz: true }).notNullable().defaultTo(knex.fn.now())
11+
table.timestamp('updated_at', { useTz: true }).notNullable().defaultTo(knex.fn.now())
12+
13+
table.index(['domain'], 'idx_nip05_verifications_domain')
14+
table.index(['is_verified'], 'idx_nip05_verifications_is_verified')
15+
table.index(['last_checked_at'], 'idx_nip05_verifications_last_checked_at')
16+
})
17+
}
18+
19+
exports.down = function (knex) {
20+
return knex.schema.dropTable('nip05_verifications')
21+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
exports.up = async function (knex) {
2+
await knex.schema.alterTable('users', (table) => {
3+
table.boolean('is_vanished').notNullable().defaultTo(false)
4+
})
5+
6+
await knex.raw(`
7+
UPDATE users u
8+
SET is_vanished = true
9+
WHERE EXISTS (
10+
SELECT 1 FROM events e
11+
WHERE e.event_pubkey = u.pubkey
12+
AND e.event_kind = 62
13+
AND e.deleted_at IS NULL
14+
)
15+
`)
16+
}
17+
18+
exports.down = function (knex) {
19+
return knex.schema.alterTable('users', (table) => {
20+
table.dropColumn('is_vanished')
21+
})
22+
}

0 commit comments

Comments
 (0)