Compare commits

..

1784 commits
v1.0.0 ... main

Author SHA1 Message Date
Alex Gleason
8182fb43c1
Display all users in nostr.json 2025-11-14 02:04:28 -06:00
Alex Gleason
370deac1af
Bump gleasonator-policy in deno.lock 2025-06-06 08:16:07 -05:00
Alex Gleason
c79cd80859
Bump gleasonator-policy in deno.lock 2025-06-06 07:11:19 -05:00
Alex Gleason
24d27c4cdd
Index I/i tags 2025-06-01 19:45:36 -05:00
Alex Gleason
96799d1918
Index kind 1111 tags 2025-06-01 14:45:29 -05:00
Alex Gleason
293a0d10fb
Bump gleasonator-policy in lockfile 2025-05-09 13:03:41 -05:00
Alex Gleason
789b6c7e93
Guard against duplicate ephemeral events being streamed 2025-05-08 19:52:41 -05:00
Alex Gleason
984f76d184
DittoPgStore: remove fulfillment batching 2025-05-08 19:42:10 -05:00
Alex Gleason
fd87bad238
Add subscriptions bytes metrics 2025-04-29 13:24:36 -05:00
Alex Gleason
808c3f70f5 Merge branch 'fix-logging-defaults' into 'main'
fix logging default config

See merge request soapbox-pub/ditto!735
2025-04-29 18:06:56 +00:00
Siddharth Singh
b75cc0e372
fix early return in jsonl path for log level 2025-04-29 23:34:46 +05:30
Siddharth Singh
319620a414
remove relative import from ditto/utils in DittoConf 2025-04-29 23:32:37 +05:30
Siddharth Singh
e2ce3f32c3
fix logging default config 2025-04-29 23:25:38 +05:30
Alex Gleason
f8d4fa57c6
Also don't log more expected SQL errors 2025-04-29 12:54:36 -05:00
Alex Gleason
49e509e420
Fix LOG_CONFIG parsing 2025-04-29 12:42:40 -05:00
Alex Gleason
3a849700db
KyselyLogger: don't log expected errors 2025-04-29 12:32:44 -05:00
Alex Gleason
3a260f7873 Merge branch '10x-better-logging' into 'main'
Make logging 10x better

See merge request soapbox-pub/ditto!734
2025-04-29 14:24:48 +00:00
Alex Gleason
f7c8024c2f Merge branch 'mint-cashu' into 'main'
Allow users to mint for new tokens (cashu)

See merge request soapbox-pub/ditto!666
2025-04-22 15:34:19 +00:00
P. Reis
9d375f4afe goose created files remove 2025-04-08 12:23:12 -03:00
P. Reis
fb7c57a1d0 Merge branch 'main' into mint-cashu
Conflicts:
	packages/ditto/interfaces/DittoEvent.ts
	packages/ditto/storages/hydrate.ts
2025-04-08 12:16:53 -03:00
P. Reis
aadc3079fa refactor: make GET wallet a bit faster 2025-04-08 12:14:47 -03:00
Siddharth Singh
1b55932193
apply review fixes (thanks @alexgleason) 2025-04-08 17:09:05 +05:30
Siddharth Singh
8305cea81e
fmt ... again 2025-04-06 15:53:06 +05:30
Siddharth Singh
a1aed97dec
enable all subscopes of a given scope when it's supplied 2025-04-06 15:50:25 +05:30
Siddharth Singh
8f51a9d6d7
only show extra params when they are actually present 2025-04-06 15:46:24 +05:30
Siddharth Singh
1b19ff415a
add types to public api for dittoconf 2025-04-06 15:40:42 +05:30
Siddharth Singh
d3a15a699e
fmt 2025-04-06 15:33:36 +05:30
Siddharth Singh
82e7f854b9
replace logi handler 2025-04-06 15:28:54 +05:30
Siddharth Singh
6778a42d54
remove isCI conf var 2025-04-06 15:28:54 +05:30
Siddharth Singh
5dc2cc405f
add log configuration variables 2025-04-06 15:28:54 +05:30
Siddharth Singh
feab5f8cd0
stop logging every single query 2025-04-06 15:28:54 +05:30
Alex Gleason
63ebad0412 Merge branch 'client-tag-improvements' into 'main'
Client tag improvements

See merge request soapbox-pub/ditto!733
2025-04-03 17:48:06 +00:00
Alex Gleason
1c2d7a6793
Index client addr in search extensions 2025-04-03 12:38:39 -05:00
Alex Gleason
621d92dcf6
Render "client" tags in statuses even if they don't have an application handler event 2025-04-03 12:31:10 -05:00
Alex Gleason
0abee76e38
nip89: add ["t", "ditto"] tag to application handler event 2025-04-03 12:29:58 -05:00
Alex Gleason
c425a9d39a
DittoPgStore: index "client" tag 2025-04-03 12:29:45 -05:00
Alex Gleason
be5c58c615 Merge branch 'client-tag' into 'main'
Support NIP-89 "client" tag

See merge request soapbox-pub/ditto!732
2025-04-02 01:38:12 +00:00
Alex Gleason
23eb531305
Render client tags 2025-04-01 20:26:05 -05:00
Alex Gleason
caf59f4078
Insert NIP-89 "client" tags when users post statuses 2025-04-01 19:49:31 -05:00
Alex Gleason
c8b1c2050b
Publish nip89 application handler on startup 2025-04-01 18:55:36 -05:00
Alex Gleason
b56fe678f2 Merge branch 'fix-close' into 'main'
Fix relay always sending a CLOSED message after the client sends CLOSE

See merge request soapbox-pub/ditto!730
2025-03-28 22:53:05 +00:00
Alex Gleason
8dc9ea98e2
Fix relay always sending a CLOSED message after the client sends CLOSE 2025-03-28 17:50:51 -05:00
Alex Gleason
98c967dd22 Merge branch 'goosehints' into 'main'
Add .goosehints file

See merge request soapbox-pub/ditto!729
2025-03-28 21:24:08 +00:00
Alex Gleason
1a6c114a57
Fix inline codeblock in .goosehints 2025-03-28 16:22:03 -05:00
Alex Gleason
34a29c8f4e
NIP-11 improvements 2025-03-28 16:15:20 -05:00
Alex Gleason
278e13a6ef
Add .goosehints file 2025-03-28 16:08:28 -05:00
P. Reis
69fe86890f feat: add accepts_zaps_cashu boolean field to DittoEvent and hydrate it 2025-03-27 09:48:29 -03:00
P. Reis
8a75f9e944 feat: implement GET statuses/:id{[0-9a-f]{64}}/nutzapped_by (with tests) 2025-03-26 15:55:59 -03:00
P. Reis
71a558a9de Merge branch 'main' into mint-cashu 2025-03-25 18:23:13 -03:00
P. Reis
cda5196007 fix: remove unused import 2025-03-25 18:22:51 -03:00
P. Reis
7dc56f594b feat: add zaps_amount_cashu to event_stats (with tests)
add zapped_cashu and zaps_amount_cashu field to MastodonStatus
2025-03-25 18:19:40 -03:00
P. Reis
83c96c88b7 feat: support pagination in GET transactions
remove getTransactions function and replace it with renderTransaction function (all tests updated)
2025-03-24 23:02:04 -03:00
Alex Gleason
95c10fd2b9 Merge branch 'fix-nip05-notification' into 'main'
Fix name grant notification not being rendered

See merge request soapbox-pub/ditto!728
2025-03-23 17:15:59 +00:00
Alex Gleason
06c9c8d898
Fix name grant notification not being rendered 2025-03-23 12:11:39 -05:00
Alex Gleason
1ff83212c4 Merge branch 'fix-index-k-tag' into 'main'
fix: index k tag even if the value is not a number and count is less than 3

See merge request soapbox-pub/ditto!727
2025-03-21 20:59:27 +00:00
P. Reis
4451aafadc fix: index k tag even if the value is not a number and count is less than 3 2025-03-21 16:56:24 -03:00
P. Reis
1360484ae9 fix: call paginationSchema as a function 2025-03-21 10:49:58 -03:00
P. Reis
0b8b9e726a Merge branch 'main' into mint-cashu 2025-03-21 10:47:49 -03:00
P. Reis
7226d503f5 fix(getTransactions): coerce tags to string in schema
This is not really needed but it doesn't hurt
2025-03-21 10:09:38 -03:00
P. Reis
d69854fa3c fix: save amount tag value as a string 2025-03-21 10:07:34 -03:00
P. Reis
f9c4ec5835 feat: create GET transactions endpoint (with tests) 2025-03-20 14:02:43 -03:00
Alex Gleason
fab34dbf5b Merge branch 'fix-mem-leak' into 'main'
Fix memory leak in relay?

See merge request soapbox-pub/ditto!726
2025-03-19 20:20:13 +00:00
Alex Gleason
8fc0092150
Fix memory leak in relay? 2025-03-19 15:15:44 -05:00
P. Reis
06ac326ec3 refactor: add relay of conf.relay in case no relays are present 2025-03-19 13:01:06 -03:00
P. Reis
feff31f094 feat: allow to edit the wallet mints and relays (with tests updated) 2025-03-18 18:30:52 -03:00
P. Reis
7c1297e865 fix: remove unused import 2025-03-17 22:48:43 -03:00
P. Reis
46ab6005d1 fix: https://jsr.io/go/slow-type-missing-explicit-type 2025-03-17 22:47:38 -03:00
P. Reis
5ff8bf4479 refactor: remove useless comments 2025-03-17 22:41:36 -03:00
P. Reis
355c53fd64 refactor: create getWallet function, with tests 2025-03-17 22:28:36 -03:00
P. Reis
07d0d4c4e5 fix: only create kind 5 if there are events to delete 2025-03-17 11:12:30 -03:00
P. Reis
c344cb6b74 refactor: call organizeProofs in a try-catch block 2025-03-17 11:10:08 -03:00
P. Reis
6afa0bb7f1 refactor: simplify deletion of expired quote ids expiredQuoteIds 2025-03-17 11:01:11 -03:00
Alex Gleason
497b02002e
streaming: ensure close handler is called even when socket is closed by server 2025-03-16 18:02:28 -05:00
Alex Gleason
f27609feb8
Set a max subscriptions size per connection 2025-03-16 17:51:07 -05:00
P. Reis
0a05dd232c fix: only create new kind 7375 if there is proofs to keep 2025-03-15 20:48:33 -03:00
P. Reis
a719c2aabf fix: add swapNutzapsMiddleware to nutzap endpoint 2025-03-15 20:33:01 -03:00
P. Reis
0e0166419e test(nutzap): add more checks 2025-03-15 20:32:20 -03:00
Alex Gleason
a6b58b50cf Merge branch 'custom-reacts' into 'main'
Support custom emoji reactions

See merge request soapbox-pub/ditto!724
2025-03-15 22:21:09 +00:00
Alex Gleason
09b0bf8ef4
Test paginationSchema with a custom limit 2025-03-15 17:20:26 -05:00
Alex Gleason
88ef8087a5
Let paginationMiddleware be configurable, add pagination to reactions handler 2025-03-15 17:18:18 -05:00
Alex Gleason
36ffd4283a
Fix DittoPgStore req test 2025-03-15 17:03:20 -05:00
Alex Gleason
006a96d0eb
Disable notify in tests 2025-03-15 16:50:26 -05:00
Alex Gleason
66979c7c11
Disallow +/- emojis in Pleroma API 2025-03-15 16:42:34 -05:00
Alex Gleason
be922bf07f
Enable pleroma_custom_emoji_reactions feature in instance endpoint 2025-03-15 16:37:00 -05:00
Alex Gleason
753413f071
Support custom emoji reactions 2025-03-15 16:32:11 -05:00
Alex Gleason
c40c6e8b30
Support custom emoji reactions in event_stats 2025-03-15 15:31:24 -05:00
Alex Gleason
755ed884d4
Pleroma API supports custom emojis with or without colons 2025-03-15 15:01:07 -05:00
Alex Gleason
1dd50e2e63
Add tests for pleromaStatusesRoute 2025-03-15 14:38:19 -05:00
Alex Gleason
f27dac342f
Small refactors to pleromaStatusesRoute 2025-03-15 13:57:06 -05:00
Alex Gleason
2f65be7dc4
Move reaction controllers to pleromaStatusesRoute 2025-03-15 13:49:42 -05:00
Alex Gleason
55a171fd2c
Merge remote-tracking branch 'origin/main' into custom-reacts 2025-03-15 13:42:00 -05:00
Alex Gleason
c2f214c9bc Merge branch 'mw-cleanup' into 'main'
Remove redundant userMiddleware usages in app.ts

See merge request soapbox-pub/ditto!723
2025-03-15 18:41:43 +00:00
Alex Gleason
c9b0ffb537
Remove redundant userMiddleware usages in app.ts 2025-03-15 13:26:55 -05:00
Alex Gleason
ed0a8dc36b Merge branch 'emoji-unauth' into 'main'
Allow custom_emojis endpoint to be accessed without a user

See merge request soapbox-pub/ditto!722
2025-03-15 18:24:52 +00:00
Alex Gleason
66dcf98a22
Allow reacting with custom emoji 2025-03-15 13:24:02 -05:00
Alex Gleason
e5dd285e6b
Allow custom_emojis endpoint to be accessed without a user 2025-03-15 12:50:05 -05:00
Alex Gleason
d0d400901c Merge branch 'custom-emojis' into 'main'
Implement custom emojis

See merge request soapbox-pub/ditto!721
2025-03-15 05:22:14 +00:00
Alex Gleason
974e07981e
getCustomEmojis: new Map() -> emojis 2025-03-15 00:19:50 -05:00
Alex Gleason
28275b7611
Insert "emoji" tags into statuses 2025-03-15 00:16:52 -05:00
Alex Gleason
b1a1ace0ac
Refactor getCustomEmojis function, support emoji categories 2025-03-14 23:58:42 -05:00
Alex Gleason
f15b6f79c0
Implement custom emojis 2025-03-14 23:36:53 -05:00
P. Reis
e1d2139c31 test: POST nutzap endpoint, with full mocks 2025-03-14 19:30:50 -03:00
P. Reis
6a24ca126a refactor(cashu): move each fetch mock to its own test 2025-03-13 17:26:40 -03:00
P. Reis
cfdd5e1929 Merge branch 'main' into mint-cashu 2025-03-13 11:51:20 -03:00
Alex Gleason
bfe693c2f8 Merge branch 'fix-pglite-closed' into 'main'
fix: Error: PGlite is closed

See merge request soapbox-pub/ditto!720
2025-03-13 14:45:40 +00:00
P. Reis
bc0580dd05 fix: Error: PGlite is closed 2025-03-13 10:45:03 -03:00
P. Reis
921f478279 Merge branch 'main' into mint-cashu 2025-03-13 10:41:17 -03:00
Alex Gleason
60fbe70212 Merge branch 'strip-media-space' into 'main'
Strip media URLs regardless of whitespace delimiter

See merge request soapbox-pub/ditto!719
2025-03-12 21:55:42 +00:00
Alex Gleason
80fcda2b01
Fix matching multiple whitespace characters at the end of a string 2025-03-12 16:53:22 -05:00
Alex Gleason
69a9534463
removeTrailingUrls -> removeTrailingTokens 2025-03-12 16:48:31 -05:00
Alex Gleason
bd71b45a8d
Strip media URLs regardless of whitespace delimiter 2025-03-12 16:46:32 -05:00
P. Reis
37d81cf2a2 Merge branch 'main' into mint-cashu 2025-03-12 17:08:02 -03:00
Alex Gleason
2e4456dba2 Merge branch 'legacy-media-strip' into 'main'
Hide media URLs from posts without imeta tags

See merge request soapbox-pub/ditto!717
2025-03-12 17:04:00 +00:00
Alex Gleason
eec78efc0e
Hide media URLs from posts without imeta tags 2025-03-12 11:56:04 -05:00
P. Reis
8d0b5ba078 test: getMintsToProofs works 2025-03-12 13:15:52 -03:00
P. Reis
803b2abacc fix: add explicit return type - tokenEventSchema 2025-03-11 12:23:04 -03:00
P. Reis
dc711bce6a fix: add explicit return type 2025-03-11 11:49:39 -03:00
P. Reis
a002b1a005 refactor: create @ditto/cashu package 2025-03-11 11:34:42 -03:00
P. Reis
1c709b04be Merge branch 'main' into mint-cashu 2025-03-10 10:46:01 -03:00
Alex Gleason
0264b16553 Merge branch 'remove-console-log' into 'main'
refactor: remove console.logs

See merge request soapbox-pub/ditto!716
2025-03-09 21:56:12 +00:00
P. Reis
3e35102e13 refactor: remove console.logs 2025-03-09 13:02:53 -03:00
Alex Gleason
592d6c1d36
Upgrade gleasonator-policy in deno.lock 2025-03-08 21:03:58 -06:00
Alex Gleason
026568ea71
Fix firehose 2025-03-08 21:03:36 -06:00
Alex Gleason
6b3f5ac8a6
Expose db to custom policy script 2025-03-08 20:44:22 -06:00
Alex Gleason
a400021a0d
Bump signal to 5s 2025-03-08 19:44:16 -06:00
Alex Gleason
3cac9b6e26 Merge branch 'link-preview-db' into 'main'
Store link previews in the database

Closes #301

See merge request soapbox-pub/ditto!715
2025-03-09 01:39:56 +00:00
Alex Gleason
26990bcf5e
Remove linkPreview cache config, rm stray console.log 2025-03-08 19:36:53 -06:00
Alex Gleason
affea45a08
Store link previews in the database
Fixes https://gitlab.com/soapbox-pub/ditto/-/issues/301
2025-03-08 19:33:15 -06:00
Alex Gleason
1abe487115 Merge branch 'lookup' into 'main'
Look up identifiers in search on remote relays

See merge request soapbox-pub/ditto!714
2025-03-09 00:41:53 +00:00
Alex Gleason
f01b4c0791
Look up identifiers in search on remote relays 2025-03-08 18:36:24 -06:00
Alex Gleason
478debfda1 Merge branch 'outboxy-req-router' into 'main'
Add an outboxy-style REQ router

See merge request soapbox-pub/ditto!713
2025-03-08 21:52:17 +00:00
Alex Gleason
239c427c78
Add DittoPool tests 2025-03-08 15:46:02 -06:00
Alex Gleason
920e558c06
Add an outboxy-style REQ router 2025-03-08 15:29:31 -06:00
Alex Gleason
7248aaf6c6 Merge branch 'req-abort' into 'main'
Fix REQ abort logic

See merge request soapbox-pub/ditto!712
2025-03-08 05:01:13 +00:00
Alex Gleason
e085082a76
Fix REQ abort logic 2025-03-07 22:58:55 -06:00
Alex Gleason
413056e841
Prewarm cards only for kind 1 2025-03-07 16:31:01 -06:00
Alex Gleason
f12cce9802 Merge branch 'fix-relay-close' into 'main'
Ensure relay close handler is called

See merge request soapbox-pub/ditto!711
2025-03-07 18:52:06 +00:00
Alex Gleason
5162e051ad
Ensure relay close handler is called 2025-03-07 12:34:47 -06:00
Alex Gleason
f8eb4fc79c
Add a metric for active author subscriptions 2025-03-06 22:55:23 -06:00
Alex Gleason
9c3307f923
Purify event before sending it out to relay 2025-03-06 15:38:14 -06:00
Alex Gleason
e5e0ddd7aa
DittoPgStore: purify events before streaming them 2025-03-06 15:34:31 -06:00
Alex Gleason
6eace14850 Merge branch 'fetch-authors' into 'main'
Automatically fetch missing authors from pool

See merge request soapbox-pub/ditto!710
2025-03-06 21:12:43 +00:00
Alex Gleason
e85e89e0af
Automatically fetch missing authors from pool 2025-03-06 14:55:40 -06:00
Alex Gleason
1ab77fdeab Merge branch 'fix-revoke-nip05' into 'main'
fix(attempt): revoke username

See merge request soapbox-pub/ditto!700
2025-03-05 23:31:17 +00:00
P. Reis
e549a9d34a refactor: stop fetching author and set nip05_last_verified_at to null 2025-03-05 20:28:22 -03:00
P. Reis
9e726baa2a refactor: remove try catch 2025-03-05 20:15:16 -03:00
P. Reis
1eb1f4206d refactor: use db.kysely.updateTable rather than db.kysely.insertInto 2025-03-05 20:12:42 -03:00
P. Reis
19244aec2c test/fix: use waitFor function 2025-03-05 19:35:25 -03:00
Alex Gleason
811a56e406
ci: try moving the timeout to the actual test job 2025-03-05 15:05:26 -06:00
Alex Gleason
9b422d8e31
Add note about hanging queries in DittoPostgres test 2025-03-05 14:47:35 -06:00
Alex Gleason
0b72533b05
DittoPglite: test that queries reject after it's closed 2025-03-05 14:06:13 -06:00
Alex Gleason
4e0479f7c8
Add DittoPostgres test 2025-03-05 13:27:34 -06:00
Alex Gleason
c7175f8301
ci: add 2 minute timeout 2025-03-05 13:02:01 -06:00
Alex Gleason
f3bdabc13a
DittoRelayStore: improve error handling around this.listen(), remove await 2025-03-05 12:44:16 -06:00
P. Reis
842150b6e2 fix: remove useless 'p' tag in admin kind 5 event 2025-03-05 11:33:57 -03:00
P. Reis
fc4f5fd522 Merge branch 'main' into fix-revoke-nip05
Conflicts:
	packages/ditto/storages/DittoRelayStore.test.ts
2025-03-05 11:25:04 -03:00
P. Reis
d8a0eca891 refactor: get author from grant event (30360), before doing the admin deletion 2025-03-05 11:22:07 -03:00
P. Reis
dd5397e795 test: check if nip05 exists and then check again to see if it's null 2025-03-05 11:02:13 -03:00
P. Reis
dfff63fab4 fix: await Promise.allSettled 2025-03-05 11:00:28 -03:00
Alex Gleason
b5858dd54c
Catch pool.query 2025-03-04 23:09:20 -06:00
Alex Gleason
815b903e28
Add a timeout on pool.query 2025-03-04 23:07:45 -06:00
Alex Gleason
773cee8b92 Merge branch 'fetch-related' into 'main'
Fetch related events by ID through the RelayStore

See merge request soapbox-pub/ditto!709
2025-03-05 04:28:48 +00:00
Alex Gleason
c5e9017d24
Fetch related events by ID through the RelayStore 2025-03-04 22:14:56 -06:00
P. Reis
ab6054efe8 Merge branch 'main' into fix-revoke-nip05
Conflicts:
	packages/ditto/controllers/api/admin.ts
	packages/ditto/storages/DittoRelayStore.test.ts
2025-03-04 14:53:21 -03:00
P. Reis
aa1311ccae fix: call store.event 2025-03-04 11:42:42 -03:00
P. Reis
c5fdc97e58 refactor: stop returning author 2025-03-04 10:51:10 -03:00
Alex Gleason
c39ea9212f
Lowercase all captcha bg filenames for suitability in a URL path 2025-03-03 19:37:35 -06:00
Alex Gleason
29109cec21
Give @ditto/ditto 1.1.0 2025-03-03 19:34:05 -06:00
Alex Gleason
2ca216dfdf
Set all packages to version 0.1.0 2025-03-03 19:31:41 -06:00
P. Reis
44d525eccb fix: use author pubkey, not admin pubkey 2025-03-03 21:17:17 -03:00
Alex Gleason
363816d930
Fix nostr.json cache by returning non-200 status 2025-03-03 17:10:46 -06:00
Alex Gleason
ff4c3381ba Merge branch 'feat-promove-admin' into 'main'
feat: promote users to admin

Closes #298

See merge request soapbox-pub/ditto!707
2025-03-03 22:56:18 +00:00
Alex Gleason
0d1b7b8d37
Fix DittoRoute test 2025-03-03 16:53:54 -06:00
Alex Gleason
8528c4c39e
Add more permission group tests 2025-03-03 16:36:38 -06:00
Alex Gleason
b7bf2fc76f
Move Pleroma permission_groups controller to its own routes file, add tests 2025-03-03 16:33:28 -06:00
Alex Gleason
d29bc8c020
Merge remote-tracking branch 'origin/main' into feat-promove-admin 2025-03-03 16:00:16 -06:00
Alex Gleason
a2f019993d
Simplify promote controller 2025-03-03 15:58:13 -06:00
Alex Gleason
10ea6f7635 Merge branch 'name-request-refactor' into 'main'
Name request refactor

See merge request soapbox-pub/ditto!708
2025-03-03 21:48:18 +00:00
P. Reis
7525cd6ef9 refactor: set nip05 to null in handleRevokeNip05 function 2025-03-03 18:42:26 -03:00
Alex Gleason
bcd2ed18ef
Fix error handling of DittoRoute 2025-03-03 15:41:24 -06:00
Alex Gleason
b8b6174fcc
Test that DittoRelayStore generates nip05 request set event 2025-03-03 15:24:26 -06:00
Alex Gleason
0dd085b559
Remove old testApp 2025-03-03 14:46:05 -06:00
Alex Gleason
9be9f7c9d0
Add tests for dittoNameRoute 2025-03-03 14:39:01 -06:00
P. Reis
28c3b07a3e fix: remove unused imports 2025-03-03 17:34:13 -03:00
P. Reis
3bcf716795 refactor: simplify promote user to admin 2025-03-03 17:32:28 -03:00
Alex Gleason
14b809b1e8
db: add TestDB module 2025-03-03 12:21:02 -06:00
Alex Gleason
a21ec4600a
Move /api/v1/ditto/names to a DittoRoute 2025-03-03 11:50:49 -06:00
Alex Gleason
59ad40fb3f
Remove extra space 2025-03-02 18:03:21 -06:00
Alex Gleason
484625842b
Skip ffmpeg tests in CI 2025-03-02 18:02:03 -06:00
Alex Gleason
ac0285293e
Remove pipelineEncounters.ts 2025-03-02 14:06:15 -06:00
Alex Gleason
2415dbe4e5 Merge branch 'transcode' into 'main'
Transcode uploaded videos with ffmpeg

See merge request soapbox-pub/ditto!706
2025-03-02 05:41:29 +00:00
Alex Gleason
7e8ff1f329
Get video dimensions from frame 2025-03-01 22:15:32 -06:00
Alex Gleason
5168ccd748
Write uploads to disk so ffmpeg can seek properly 2025-03-01 20:59:14 -06:00
Alex Gleason
c2e6e10a3a
Don't call ffprobe unless mediaTranscode is enabled 2025-03-01 18:03:57 -06:00
Alex Gleason
3035ecaca9
Make transcoding optional, refactor a bit 2025-03-01 17:45:01 -06:00
Alex Gleason
414a3b7651
Let FFMPEG_PATH and FFPROBE_PATH be configurable 2025-03-01 17:01:39 -06:00
Alex Gleason
8a94be803d
Give transcoded videos the proper file type 2025-03-01 16:39:09 -06:00
Alex Gleason
8c61efd75e
Improve blurhash performance of HD images 2025-03-01 13:56:17 -06:00
Alex Gleason
9051a59733
Measure performance of uploads 2025-03-01 13:09:42 -06:00
Alex Gleason
bd4c94852f
Call ffprobe, improve transcoding 2025-02-28 21:21:30 -06:00
Alex Gleason
2533d2f469
Support readable in extractVideoFrame 2025-02-28 20:52:11 -06:00
Alex Gleason
a28e6509fd
Make analyze return a lot more information 2025-02-28 19:48:53 -06:00
Alex Gleason
ad9cc676e6
Improve getVideoDimensions 2025-02-28 18:41:13 -06:00
Alex Gleason
5f10f92d4e
Let ffprobe pipe data to stdin 2025-02-28 18:29:41 -06:00
P. Reis
c79867d8ca feat: promote users to admin 2025-02-28 18:25:34 -03:00
Alex Gleason
d70a00a8ca
Expose thumb and image to Attachment view, don't set thumb (since it's redundant with image) 2025-02-28 10:51:08 -06:00
Alex Gleason
6774975051
Get blurhash and dimensions of video 2025-02-28 10:24:45 -06:00
Alex Gleason
7ecca587a9
ffmpeg: explicitly set stdin to null 2025-02-28 10:20:47 -06:00
Alex Gleason
aeaa60df45
transcode: add -nostdin -safe 1 2025-02-28 10:17:39 -06:00
Alex Gleason
43ec58085a
Extract a poster image from videos (not efficient yet) 2025-02-28 09:58:28 -06:00
Alex Gleason
813026e734
Transcode video before uploading 2025-02-28 09:36:49 -06:00
P. Reis
dcfdfb1c7f Merge branch 'main' into mint-cashu
Conflicts:
	packages/ditto/controllers/api/cashu.ts
2025-02-28 10:51:02 -03:00
P. Reis
822f623018 refactor: this.handleRevokeNip05 before relay.event 2025-02-28 10:19:10 -03:00
Alex Gleason
26ca4aa7f7
Go back to just installing ffmpeg with apt 2025-02-28 00:01:28 -06:00
Alex Gleason
57c1871852
Try installing ffmpeg with curl 2025-02-27 23:54:06 -06:00
Alex Gleason
39821f8371
Install ffmpeg in GitLab CI 2025-02-27 23:47:27 -06:00
Alex Gleason
4f2aad9c5d
Export stuff from transcode/mod.ts 2025-02-27 23:42:29 -06:00
Alex Gleason
8f02c4125a
Add ffprobe module 2025-02-27 23:38:57 -06:00
Alex Gleason
e46b7bfa85
Rework ffmpeg to accept file URIs 2025-02-27 23:19:27 -06:00
Alex Gleason
d36efb7a30
transcode: export existing code in mod.ts 2025-02-27 22:06:03 -06:00
Alex Gleason
6ce64822e1
Split transcode and ffmpeg into separate modules 2025-02-27 21:59:19 -06:00
Alex Gleason
bb13a8dc71
Add ffmpeg module 2025-02-27 21:34:05 -06:00
Alex Gleason
bd47ae5930
Add @ditto/transcode package 2025-02-27 21:22:19 -06:00
Alex Gleason
462c00a3e7
transcode: simplify pipe 2025-02-27 20:16:25 -06:00
Alex Gleason
044930cc8d
transcodeVideoStream -> transcodeVideo 2025-02-27 20:08:26 -06:00
Alex Gleason
25d5db8db6
transcode: use a structured object for ffmpeg options 2025-02-27 20:07:28 -06:00
Alex Gleason
82f16e0cfe
Add transcode module 2025-02-27 20:01:11 -06:00
Alex Gleason
5fc874b768 Merge branch 'deno-2.2.2' into 'main'
Upgrade Deno to v2.2.2

See merge request soapbox-pub/ditto!705
2025-02-28 01:21:25 +00:00
Alex Gleason
96c845205b
Upgrade Deno to v2.2.2 2025-02-27 19:19:33 -06:00
Alex Gleason
381cbfd36f
Add ip to logiMiddleware 2025-02-27 18:24:05 -06:00
Alex Gleason
d458fc8464 Merge branch 'request-id' into 'main'
Add requestId middleware

See merge request soapbox-pub/ditto!704
2025-02-28 00:10:49 +00:00
Alex Gleason
368bf91b1f
Log requestId in some convenient spots 2025-02-27 18:08:55 -06:00
Alex Gleason
0cdb7b8cd5
Add requestId middleware 2025-02-27 17:57:22 -06:00
Alex Gleason
f683642478 Merge branch 'upload-conf' into 'main'
Remove `@/config.ts` import from utils/upload.ts

See merge request soapbox-pub/ditto!703
2025-02-27 23:37:57 +00:00
Alex Gleason
ee58a9f265 Merge branch 'metadata-conf' into 'main'
Remove `@/config.ts` import from utils/instance.ts

See merge request soapbox-pub/ditto!702
2025-02-27 23:34:46 +00:00
Alex Gleason
1bce9e2982
Remove @/config.ts import from utils/upload.ts 2025-02-27 17:34:35 -06:00
Alex Gleason
2acd23ebbe
Remove @/config.ts import from utils/instance.ts 2025-02-27 17:32:54 -06:00
Alex Gleason
f7ab4a6763 Merge branch 'stats-conf' into 'main'
Remove `@/config.ts` import from utils/stats.ts

See merge request soapbox-pub/ditto!701
2025-02-27 22:58:12 +00:00
Alex Gleason
70d8c2ed59
DittoPgStore: destructure conf 2025-02-27 16:54:12 -06:00
Alex Gleason
7e00b9f9a2
Add PolicyWorker test 2025-02-27 16:52:09 -06:00
Alex Gleason
5f5d0bc324
Remove @/config.ts import from utils/stats.ts 2025-02-27 16:35:06 -06:00
P. Reis
4792e568ef fix: event.pubkey, not event.id in p tag 2025-02-27 19:15:33 -03:00
P. Reis
e6f4f8d23e fix(attempt): revoke username 2025-02-27 19:10:13 -03:00
Alex Gleason
ddf1a9d6dc Merge branch 'pleroma-conf' into 'main'
Remove `@/config.ts` import from utils/pleroma.ts

See merge request soapbox-pub/ditto!699
2025-02-27 20:27:21 +00:00
Alex Gleason
7fe06753aa
Remove @/config.ts import from utils/pleroma.ts 2025-02-27 14:25:09 -06:00
Alex Gleason
fa0add60d5 Merge branch 'note-conf' into 'main'
Remove `@/config.ts` import from utils/note.ts

See merge request soapbox-pub/ditto!698
2025-02-27 20:16:53 +00:00
Alex Gleason
0e667995c1
Remove @/config.ts import from utils/note.ts 2025-02-27 14:15:02 -06:00
Alex Gleason
c07c88f2f5 Merge branch 'zapsplit-conf' into 'main'
Remove `@/config.ts` import from utils/zap-split.ts

See merge request soapbox-pub/ditto!697
2025-02-27 20:04:34 +00:00
Alex Gleason
2266152df3
Remove @/config.ts import from utils/zap-split.ts 2025-02-27 14:02:44 -06:00
Alex Gleason
549f3ebc5d Merge branch 'conf-tests' into 'main'
Remove `@/config.ts` imports from tests

See merge request soapbox-pub/ditto!696
2025-02-27 19:57:48 +00:00
Alex Gleason
23b8edefef
Remove @/config.ts imports from tests 2025-02-27 13:56:02 -06:00
Alex Gleason
4b1d7c1502 Merge branch 'sentry-conf' into 'main'
Remove `@/config.ts` import when starting Sentry

See merge request soapbox-pub/ditto!695
2025-02-27 19:53:51 +00:00
Alex Gleason
432f65ff61
Remove @/config.ts import when starting Sentry 2025-02-27 13:51:57 -06:00
Alex Gleason
92da5e6ac3
Actually fix policy.worker import (hack) 2025-02-26 18:19:30 -06:00
Alex Gleason
55115d3592
PolicyWorker: move Deno.env set above imports 2025-02-26 18:14:42 -06:00
Alex Gleason
ccf6d2074e Merge branch 'mastoapi-entities' into 'main'
Move ditto/interfaces to @ditto/mastoapi/types

See merge request soapbox-pub/ditto!693
2025-02-27 00:03:45 +00:00
Alex Gleason
b81da2c0d7
Move ditto/interfaces to @ditto/mastoapi/types 2025-02-26 18:01:32 -06:00
P. Reis
7e4e6635ad fix: type error 2025-02-26 20:54:11 -03:00
P. Reis
53f83f78c7 Merge branch 'main' into mint-cashu 2025-02-26 20:48:38 -03:00
P. Reis
8479143ed8 refactor: minimalist check of status_id and account_id 2025-02-26 20:48:12 -03:00
Alex Gleason
466245633c Merge branch 'fix-ensure-remove-exists' into 'main'
fix: call remove if it's available

See merge request soapbox-pub/ditto!692
2025-02-26 23:43:25 +00:00
P. Reis
0f20f1b26b refactor: return 500 http code in case of error 2025-02-26 20:21:42 -03:00
P. Reis
0c7ab03643 refactor: use ?. 2025-02-26 20:06:57 -03:00
P. Reis
40824280b4 fix: call remove if it's available 2025-02-26 19:53:55 -03:00
Alex Gleason
ec3fa3daeb Merge branch 'rm-config' into 'main'
Remove precheck.ts, perform check in DittoConf constructor

See merge request soapbox-pub/ditto!691
2025-02-26 22:30:27 +00:00
Alex Gleason
f650541b23
Remove precheck.ts, perform check in DittoConf constructor 2025-02-26 16:16:40 -06:00
Alex Gleason
7256b5dcf8 Merge branch 'dittoapp-opts' into 'main'
DittoApp: combine opts and vars into one object

See merge request soapbox-pub/ditto!690
2025-02-26 21:21:21 +00:00
Alex Gleason
89905d76a6
DittoApp: combine opts and vars into one object 2025-02-26 15:19:20 -06:00
Alex Gleason
c889cd68d2 Merge branch 'ditto-captcha' into 'main'
Add @ditto/captcha package

See merge request soapbox-pub/ditto!689
2025-02-26 21:14:25 +00:00
Alex Gleason
4b55acb796
Clean up captchaController 2025-02-26 15:10:41 -06:00
Alex Gleason
a2aaa55b89
Add tests to captcha modules 2025-02-26 15:09:01 -06:00
Alex Gleason
5f617b2d1a
Break captcha package into smaller modules 2025-02-26 14:53:13 -06:00
Alex Gleason
a2732642a5
Break @ditto/captcha into a separate library 2025-02-26 14:46:47 -06:00
Alex Gleason
4b321f21fc Merge branch 'refactor-remove-await' into 'main'
refactor: remove await

See merge request soapbox-pub/ditto!688
2025-02-26 14:30:54 +00:00
P. Reis
1730274e70 refactor: remove await 2025-02-26 11:19:15 -03:00
Alex Gleason
e17360d49c Merge branch 'fix-mentions-bug' into 'main'
fix: filter out invalid pubkeys

Closes #290

See merge request soapbox-pub/ditto!687
2025-02-25 23:26:22 +00:00
P. Reis
c82cfb9e8b refactor: remove duplicate filter 2025-02-25 20:16:28 -03:00
P. Reis
05a4a5a5c9 fix: filter out invalid pubkeys 2025-02-25 20:04:28 -03:00
P. Reis
cf4d888ad5 fix: total balance can be equal to the amount, access undefined with ? 2025-02-25 16:20:40 -03:00
P. Reis
e08603a42a fix: get lock pubkey from nutzap info 2025-02-25 15:59:40 -03:00
P. Reis
51faffc9e2 fix: get mints from nutzap info 2025-02-25 15:56:41 -03:00
P. Reis
33b8078fc6 fix: add pubkey lock to proofs 2025-02-25 13:58:57 -03:00
P. Reis
99a20bd129 Merge branch 'main' into mint-cashu
Conflicts:
	packages/ditto/controllers/api/cashu.ts
	packages/ditto/middleware/swapNutzapsMiddleware.ts
2025-02-24 20:07:12 -03:00
P. Reis
1d2a317029 feat: nutzap a post or user (no tests) 2025-02-24 17:34:14 -03:00
Alex Gleason
73beef72ac Merge branch 'pool-whoops' into 'main'
Switch the pools, whoops

See merge request soapbox-pub/ditto!686
2025-02-24 14:51:55 +00:00
Alex Gleason
11a589fb01
Switch the pools, whoops 2025-02-24 08:50:06 -06:00
Alex Gleason
e78e0c2460
Upgrade Nostrify 2025-02-23 23:08:46 -06:00
Alex Gleason
40221410e8 Merge branch 'apistore' into 'main'
Replace pipeline with DittoAPIStore

See merge request soapbox-pub/ditto!685
2025-02-24 03:05:42 +00:00
Alex Gleason
9df50a5b0d
app.ts: minor variable name cleanup 2025-02-23 20:53:48 -06:00
Alex Gleason
751c09035c
Pass DittoAPIStore to MastoAPI endpoints, DittoRelayStore to /relay 2025-02-23 19:41:17 -06:00
Alex Gleason
cce78f2b0c
Make DittoAPIStore and DittoRelay separate things 2025-02-23 18:54:04 -06:00
P. Reis
61cc7c335a feat: create organizedProofs function
test: organizedProofs function
2025-02-23 21:06:34 -03:00
Alex Gleason
52a9017730
Add a new DittoAPIStore extending DittoRelayStore 2025-02-23 18:03:41 -06:00
Alex Gleason
ec498653fb
Rename DittoAPIStore to DittoRelayStore 2025-02-23 18:02:45 -06:00
Alex Gleason
77c0ac3561
Hotfix for relay publishing 2025-02-23 14:55:19 -06:00
Alex Gleason
e88a7d01d4
Purify event before sending to pool 2025-02-23 14:50:45 -06:00
Alex Gleason
e99496306a
DittoAPIStore: fix handleEvent not being called 2025-02-23 13:08:19 -06:00
Alex Gleason
44f3721d36
DittoAPIStore: test that kind 0 with nip05 updates author_stats table 2025-02-23 12:41:59 -06:00
Alex Gleason
3f9f0468d2
Remove now unnecessary idleTimeout opt from socket upgrades 2025-02-23 12:05:53 -06:00
Alex Gleason
decb3ac618
Fix streaming API hydration ( ͡° ͜ʖ ͡°) 2025-02-23 11:56:29 -06:00
Alex Gleason
a52fe9fbc6
Try to fix pkey migration 2025-02-23 09:30:00 -06:00
Alex Gleason
02d4235abd
Rename nostr_events_new_pkey to nostr_events_pkey 2025-02-23 09:21:14 -06:00
Alex Gleason
497d5d12c9
Fix DittoPgStore tests 2025-02-23 00:39:41 -06:00
Alex Gleason
a9c696936b
Upgrade Nostrify 2025-02-23 00:11:42 -06:00
Alex Gleason
237f6e55ad
Fix DittoEnv type check 2025-02-22 21:52:26 -06:00
Alex Gleason
f1cb8c778a
Normalize Link header URLs 2025-02-22 21:45:04 -06:00
Alex Gleason
7f059b4dac
Fix event hydration with getEvent/getAuthor 2025-02-22 21:40:53 -06:00
Alex Gleason
6f1312b67f
Remove old paginationSchema 2025-02-22 21:38:48 -06:00
Alex Gleason
979f2cffb4
Fix stats:recompute script 2025-02-22 21:30:57 -06:00
Alex Gleason
1ae9da5793
Fix hydrate tests 2025-02-22 21:26:23 -06:00
Alex Gleason
6cd64500ce
Fix stats test 2025-02-22 21:24:43 -06:00
Alex Gleason
4f46a69131
I did a fucked up polymorphism 2025-02-22 20:56:53 -06:00
Alex Gleason
f893a81464
DittoAPIStore: add limit 0 2025-02-22 19:55:58 -06:00
Alex Gleason
70f0eb3b03
Fix pagination lint errors 2025-02-22 19:49:43 -06:00
Alex Gleason
f2e2072184
Export PolicyWorker as a regular class 2025-02-22 19:46:38 -06:00
Alex Gleason
3b17fd9b45
Remove @/storages.ts (jesus christ) 2025-02-22 19:27:53 -06:00
Alex Gleason
ca5c887705
Remove storages.ts from scripts 2025-02-22 15:54:31 -06:00
Alex Gleason
63c0f8b032
ditto/db: make adapters use classes instead of static classes 2025-02-22 15:32:47 -06:00
Alex Gleason
398d79b45e
DittoAPIStore: console.error -> logi 2025-02-22 13:05:50 -06:00
Alex Gleason
79fc568548
Add DittoPool class 2025-02-22 12:59:36 -06:00
Alex Gleason
2f0dbc44e4
Copy all the pipeline logic into DittoAPIStore (and some into DittoPgStore) 2025-02-22 12:01:50 -06:00
Alex Gleason
48bd7618f7
Start building DittoAPIStore 2025-02-22 03:13:05 -06:00
Alex Gleason
02e284f3aa
Remove unused DittoFilter interface 2025-02-22 01:06:53 -06:00
Alex Gleason
045eb4e1d6 Merge branch 'router' into 'main'
Switch to @ditto/router

See merge request soapbox-pub/ditto!683
2025-02-22 07:05:11 +00:00
Alex Gleason
4ed0640766
@ditto/router -> @ditto/mastoapi/router 2025-02-21 23:32:15 -06:00
Alex Gleason
ecb2b8d8f1 Merge branch 'lowercase-nip05' into 'main'
Make NIP-05 case insensitive

See merge request soapbox-pub/ditto!684
2025-02-22 03:59:20 +00:00
Alex Gleason
084c6aa944
Fix DummyDB test 2025-02-21 21:55:00 -06:00
Alex Gleason
8ef03e7926
Merge remote-tracking branch 'origin/lowercase-nip05' into router 2025-02-21 21:54:32 -06:00
Alex Gleason
6c70b4bc4e
Make NIP-05 case insensitive 2025-02-21 21:51:33 -06:00
Alex Gleason
07b68b71d2
Add missing types to testApp 2025-02-21 21:31:42 -06:00
Alex Gleason
9c97cc387f
mastoapi: add a test module 2025-02-21 21:15:57 -06:00
Alex Gleason
d4fc10fe3e
Add userMiddleware tests 2025-02-21 21:09:22 -06:00
Alex Gleason
403b16a67b
Merge remote-tracking branch 'origin/main' into router 2025-02-21 20:51:33 -06:00
Alex Gleason
4cfb6543c7
Don't lowercase nip05 name before fetching (for now) 2025-02-21 20:50:09 -06:00
Alex Gleason
8437da1200
Fix error handling in nameRequestController 2025-02-21 20:33:44 -06:00
Alex Gleason
5fec5deb06
publishEvent: publish to pool in background, catch errors and log 2025-02-21 20:22:58 -06:00
Alex Gleason
82446e3ef1
Add method and pathname to ditto.http error 2025-02-21 20:06:39 -06:00
Alex Gleason
d2abb1f1e4
Fix MuteListPolicy test 2025-02-21 18:59:14 -06:00
Alex Gleason
6b1aadc24c
nip98: add explicit types to exported functions 2025-02-21 18:46:43 -06:00
Alex Gleason
26e87b3962
tokenMiddleware: pass token to streaming API 2025-02-21 17:44:56 -06:00
Alex Gleason
806bfc1b45
Delete auth98Middleware, replace with userMiddleware 2025-02-21 16:54:38 -06:00
Alex Gleason
adeff1cae5
tokenMiddleware: support nip98 auth 2025-02-21 15:53:29 -06:00
Alex Gleason
f0add87c6d
Create @ditto/nip98 package 2025-02-21 15:35:03 -06:00
Alex Gleason
72851bc536
Remove AdminStore from storages 2025-02-21 15:08:58 -06:00
Alex Gleason
e5657d67c0
app -> route 2025-02-21 15:08:37 -06:00
Alex Gleason
d0c7cc7a45
Improve cashu test 2025-02-21 15:05:54 -06:00
Alex Gleason
438ab09216
Split userMiddleware into tokenMiddleware and a new userMiddleware 2025-02-21 14:52:17 -06:00
P. Reis
ac684194a0 feat: create tokenEventSchema and add tests for cashu schemas 2025-02-21 16:48:44 -03:00
Alex Gleason
5ad7f1d5d7
userMiddleware -> tokenMiddleware 2025-02-21 13:27:19 -06:00
P. Reis
08d2f7fe3f refactor: add cashu proof schema 2025-02-21 11:41:45 -03:00
Alex Gleason
f83925331a
Apply the UserStore to the userMiddleware 2025-02-20 20:04:57 -06:00
Alex Gleason
8f49b99935
Consolidate AdminStore and UserStore 2025-02-20 20:03:31 -06:00
Alex Gleason
8a978b088b
Use the user's store in a few places where it matters 2025-02-20 18:57:55 -06:00
Alex Gleason
33786d2e5d
Fix cashu tests, sorta 2025-02-20 18:48:44 -06:00
P. Reis
d87f650da3 fix: remove unused imports 2025-02-20 19:36:02 -03:00
P. Reis
a6fba9c8f1 fix: remove unused imports 2025-02-20 19:34:58 -03:00
P. Reis
d98a4bd263 refactor: use validateAndParseWallet function in GET /wallet 2025-02-20 19:33:25 -03:00
P. Reis
36640dd400 refactor: explain better the 'toBeRedeemed' field 2025-02-20 19:21:20 -03:00
P. Reis
71fd6ef965 refactor: extract repetitive validation and put it into a new function called 'validateAndParseWallet', tests included 2025-02-20 19:12:35 -03:00
Alex Gleason
e1bf86eb21
Make auth middleware work again (in a hacky way for now) 2025-02-20 14:45:44 -06:00
Alex Gleason
67aec57990
Rename @ditto/api to @ditto/mastoapi, start using the new router and middleware in app 2025-02-20 14:29:22 -06:00
Alex Gleason
22d7a5fa55
Merge remote-tracking branch 'origin/main' into router 2025-02-20 12:07:18 -06:00
Alex Gleason
64e71b0ba8 Merge branch 'rm-admin-signer' into 'main'
Remove AdminSigner, Conf.pubkey, Conf.nsec, add Conf.signer

See merge request soapbox-pub/ditto!682
2025-02-20 18:07:01 +00:00
Alex Gleason
0841563d69
Remove AdminSigner, Conf.pubkey, Conf.nsec, add Conf.signer 2025-02-20 12:04:52 -06:00
Alex Gleason
6bdb613522
Merge remote-tracking branch 'origin/main' into router 2025-02-20 11:37:33 -06:00
Alex Gleason
5ad38b4058 Merge branch 'dittodb' into 'main'
Swap the names of DittoDB and DittoDatabase, rename DittoDatabase to DittoPolyPg

See merge request soapbox-pub/ditto!681
2025-02-20 17:37:25 +00:00
Alex Gleason
44c4b3188c
DittoPolyPg: fix path to migrations 2025-02-20 11:35:37 -06:00
Alex Gleason
5231c8a94f
Rename DittoDatabase to DittoPolyPg 2025-02-20 11:32:04 -06:00
Alex Gleason
c7624e99d7
Swap the names of DittoDB and DittoDatabase 2025-02-20 11:26:27 -06:00
Alex Gleason
5c0a350776
Add @ditto/router package 2025-02-20 11:19:50 -06:00
Alex Gleason
f5947eda8b Merge branch 'deepl-fix' into 'main'
Fix DeepL Response parsing, mock DeepL tests so they can always run without API keys

See merge request soapbox-pub/ditto!680
2025-02-20 17:10:03 +00:00
Alex Gleason
91f9bd9442
Add mock LibreTranslate tests 2025-02-20 11:07:41 -06:00
Alex Gleason
1afb09e604
DittoTranslator: source_lang -> sourceLang 2025-02-20 10:39:31 -06:00
Alex Gleason
2150259aba
languageSchema does not lowercase the code 2025-02-20 10:36:43 -06:00
Alex Gleason
d791a9b350
Fix DeepL Response parsing, mock DeepL tests so they can always run without API keys 2025-02-20 10:35:27 -06:00
Alex Gleason
403d0ac5c2
Add logi log to translate controller 2025-02-20 10:03:01 -06:00
P. Reis
c530aa310d fix: get multiple proofs from nutzap event 2025-02-20 11:27:50 -03:00
Alex Gleason
2ce283e9a5
return new Response() -> return c.newResponse() 2025-02-20 00:57:47 -06:00
Alex Gleason
f72fcdbd65
Upgrade socket before closing with 1008 (ratelimit) 2025-02-20 00:23:06 -06:00
Alex Gleason
e2f23e51d2 Merge branch 'rm-pubsub' into 'main'
Remove pubsub storage

See merge request soapbox-pub/ditto!676
2025-02-20 05:13:11 +00:00
Alex Gleason
521b63185b
Catch webPush 2025-02-19 22:14:38 -06:00
Alex Gleason
351d03bde7
Remove accidentally added DittoAPIStore 2025-02-19 22:02:49 -06:00
Alex Gleason
841b83f573
Hopeless Cashu tests leak even more 2025-02-19 22:01:16 -06:00
Alex Gleason
6f7fc11635
Super duper extra close the database 2025-02-19 22:00:09 -06:00
Alex Gleason
c6605ece77
Fix not being able to log in for chrissakes 2025-02-19 21:50:19 -06:00
Alex Gleason
aefa6bed6e
Add an initial limit back to the relay 2025-02-19 20:51:07 -06:00
Alex Gleason
9401c0e013
DittoPgStore: call expandFilters in .req 2025-02-19 20:40:30 -06:00
Alex Gleason
d05dd16507
EOSE after empty initial filters 2025-02-19 20:29:24 -06:00
Alex Gleason
f0c7ec0a99
Prevent the streaming API from paginating the whole database 2025-02-19 20:25:12 -06:00
Alex Gleason
f87f19d06c
DittoPgStore: rework realtime streaming so it actually works 2025-02-19 20:17:53 -06:00
P. Reis
741df0bee6 reminder: fix not getting multiple proofs 2025-02-19 21:26:34 -03:00
Alex Gleason
bc0830785a
Remove old startNotify code 2025-02-19 16:19:16 -06:00
Alex Gleason
d9a466c0ee
Remove InternalRelay (pubsub) store 2025-02-19 16:13:22 -06:00
Alex Gleason
6568dca191
DittoPgStore: support timeout in req, add special treatment for ephemeral events, yield event loop when processing many subscriptions 2025-02-19 15:55:09 -06:00
Alex Gleason
31044691e1
Merge remote-tracking branch 'origin/main' into rm-pubsub 2025-02-19 12:03:12 -06:00
P. Reis
e9210118b0 fix: pass mintUrl rather than mint instance 2025-02-19 11:34:33 -03:00
P. Reis
04d710b1b8 fix: return mints from the wallet, not just the ones from kind 7375 2025-02-19 11:14:05 -03:00
Alex Gleason
f86d1f1cad Merge branch 'deno-2.2.0' into 'main'
Upgrade Deno to v2.2.0

See merge request soapbox-pub/ditto!679
2025-02-19 02:06:08 +00:00
Alex Gleason
7deec54a2e
Upgrade Deno to v2.2.0 2025-02-18 20:04:23 -06:00
P. Reis
d055c80abe fix: pipe json payload into desired schema 2025-02-18 22:29:39 -03:00
P. Reis
a2165f0918 refactor: implement getMintsToProofs function 2025-02-18 22:19:41 -03:00
P. Reis
8890311e2d refactor: create getLastRedeemedNutzap function 2025-02-18 21:03:12 -03:00
Alex Gleason
3ed75434fe Merge branch 'genevent' into 'main'
Switch to genEvent from Nostrify

See merge request soapbox-pub/ditto!678
2025-02-18 22:37:55 +00:00
Alex Gleason
c29fc57a8c
Switch to genEvent from Nostrify 2025-02-18 16:35:45 -06:00
Alex Gleason
32813485a5 Merge branch 'rm-search-store' into 'main'
Remove SearchStore

See merge request soapbox-pub/ditto!677
2025-02-18 21:09:56 +00:00
Alex Gleason
aabe6350a7
Remove SearchStore 2025-02-18 15:08:00 -06:00
P. Reis
839aaca179 refactor: use zod 2025-02-18 17:13:16 -03:00
Alex Gleason
6fb873e72f
Make DittoPgStore pubsub capable 2025-02-18 13:45:14 -06:00
Alex Gleason
37f418899b
EventsDB -> DittoPgStore 2025-02-18 13:32:32 -06:00
Alex Gleason
3e7f33a63d Merge branch 'ditto-ratelimiter' into 'main'
Make @ditto/ratelimiter its own package

See merge request soapbox-pub/ditto!675
2025-02-18 19:18:44 +00:00
Alex Gleason
ac3a9fdf5a
Make @ditto/ratelimiter its own package 2025-02-18 13:16:42 -06:00
Alex Gleason
fc2928e72e Merge branch 'ditto-policies' into 'main'
Make @ditto/policies its own package

See merge request soapbox-pub/ditto!674
2025-02-18 19:14:38 +00:00
Alex Gleason
6f9081bbaf
Make @ditto/policies its own package 2025-02-18 13:13:05 -06:00
Alex Gleason
c029520937 Merge branch 'ditto-translators' into 'main'
Make @ditto/translators its own package

See merge request soapbox-pub/ditto!673
2025-02-18 19:07:33 +00:00
Alex Gleason
025a86fda2
translators: add missing return types 2025-02-18 13:05:47 -06:00
Alex Gleason
990646da26
Make @ditto/translators its own package 2025-02-18 13:03:48 -06:00
Alex Gleason
e163fcfa80 Merge branch 'ditto-lang' into 'main'
Make @ditto/lang its own package

See merge request soapbox-pub/ditto!672
2025-02-18 18:50:51 +00:00
Alex Gleason
d901a722e5
Make @ditto/lang its own package 2025-02-18 12:49:19 -06:00
Alex Gleason
7ef4fcecd3 Merge branch 'ditto-uploaders' into 'main'
Move uploaders into @ditto/uploaders

See merge request soapbox-pub/ditto!671
2025-02-18 18:45:34 +00:00
Alex Gleason
b2cd5c541b
Move uploaders into @ditto/uploaders 2025-02-18 12:43:57 -06:00
P. Reis
4b49dd0ddf refactor: delete get quote id state 2025-02-17 21:05:25 -03:00
P. Reis
fb72038373 feat: implement POST '/api/v1/ditto/cashu/mint/:quote_id' 2025-02-17 15:16:16 -03:00
P. Reis
29b1a20193 Merge branch 'main' into mint-cashu 2025-02-17 10:58:08 -03:00
P. Reis
b9d813804e feat: implement GET '/api/v1/ditto/cashu/quote/:quote_id' (not tested) 2025-02-16 20:00:14 -03:00
Alex Gleason
9e9a784416 Merge branch 'fix-policy-path' into 'main'
Fix path to datadir and custom policies

See merge request soapbox-pub/ditto!669
2025-02-16 18:54:08 +00:00
Alex Gleason
af0e688ca3
Fix path to datadir and custom policies 2025-02-16 12:52:27 -06:00
Alex Gleason
561efeffde Merge branch 'ditto-metrics' into 'main'
Add @ditto/metrics package

See merge request soapbox-pub/ditto!668
2025-02-16 18:03:47 +00:00
Alex Gleason
0ace14ffbb
metrics: add types to all exports 2025-02-16 11:56:41 -06:00
Alex Gleason
e100f72a9b
Add deno task lint 2025-02-16 11:53:34 -06:00
Alex Gleason
785ba1e053
Remove base alias from packages (make scripts use relative paths for now) 2025-02-16 11:50:25 -06:00
Alex Gleason
fbb5c63c33
metrics: make 'prefix' a variable 2025-02-16 11:45:08 -06:00
Alex Gleason
e1c1967a66
db: remove some external deps 2025-02-16 11:42:48 -06:00
Alex Gleason
dbfd759fba
Merge remote-tracking branch 'origin/main' into ditto-metrics 2025-02-16 00:45:01 -06:00
Alex Gleason
84493ceacc Merge branch 'ditto-db' into 'main'
Add @ditto/db package

See merge request soapbox-pub/ditto!667
2025-02-16 06:44:48 +00:00
Alex Gleason
425e0bf3f0
ci: deno lint --allow-import 2025-02-16 00:43:10 -06:00
Alex Gleason
4e0bb16b85
Fix db tests 2025-02-16 00:39:00 -06:00
Alex Gleason
739153afc9
Add @ditto/metrics package 2025-02-16 00:30:00 -06:00
Alex Gleason
773b5da461
Add db tests 2025-02-16 00:21:41 -06:00
Alex Gleason
c59bb421c6
Add @ditto/db package 2025-02-16 00:14:41 -06:00
Alex Gleason
a9744ff4ad
Add streak.expires to the API 2025-02-15 23:23:04 -06:00
Alex Gleason
222bf84eab
More msg tweaks 2025-02-15 23:05:41 -06:00
Alex Gleason
7622230c19
logi: ditto.relay.message -> ditto.relay.msg 2025-02-15 22:51:49 -06:00
Alex Gleason
aefc8c7163
Log verb with ditto.relay.message 2025-02-15 22:47:11 -06:00
P. Reis
8cba937962 Merge branch 'main' into mint-cashu
Conflicts:
	packages/ditto/controllers/api/cashu.ts
2025-02-15 21:59:12 -03:00
Alex Gleason
7fb60f6d1b Merge branch 'rm-conf' into 'main'
Replace `import Conf` calls with Hono context in some places

See merge request soapbox-pub/ditto!665
2025-02-16 00:52:42 +00:00
Alex Gleason
3073777d9b
Fix cashu tests 2025-02-15 18:51:15 -06:00
P. Reis
3bafb439bb feat: create POST '/api/v1/ditto/cashu/quote' endpoint
also create GET /quote/:quote_id and POST /mint/:quote_id endpoints (they are not implemented)
2025-02-15 21:44:43 -03:00
Alex Gleason
d0d37f5948
Remove Conf from middleware 2025-02-15 18:43:59 -06:00
Alex Gleason
8d2c83bb09
Remove Conf from S3Uploader, uploaderMiddleware 2025-02-15 18:38:20 -06:00
Alex Gleason
478c77bb62
Eliminate Conf from most controllers 2025-02-15 18:34:43 -06:00
Alex Gleason
cfd4d6bda5 Merge branch 'ditto-conf' into 'main'
@ditto/config -> @ditto/conf, DittoConfig -> DittoConf

See merge request soapbox-pub/ditto!664
2025-02-16 00:00:02 +00:00
Alex Gleason
02a7305ee9
@ditto/config -> @ditto/conf, DittoConfig -> DittoConf 2025-02-15 17:58:24 -06:00
Alex Gleason
3d2816dd05 Merge branch 'conf-mw' into 'main'
Add @ditto/api package with conf middleware

See merge request soapbox-pub/ditto!663
2025-02-15 23:56:14 +00:00
Alex Gleason
665be0c1b2
Add @ditto/api package with conf middleware 2025-02-15 17:54:38 -06:00
Alex Gleason
28f6ec8fc5 Merge branch 'ditto-config' into 'main'
Add a @ditto/config package, refactor config

See merge request soapbox-pub/ditto!662
2025-02-15 23:04:53 +00:00
Alex Gleason
9bfc7e6fe3
DittoConfig: fix missing return type of .external() 2025-02-15 17:02:53 -06:00
Alex Gleason
a2f273287d
config: test defaults 2025-02-15 16:59:12 -06:00
Alex Gleason
1e5278dc8c
Add basic DittoConfig tests 2025-02-15 16:55:59 -06:00
Alex Gleason
13db5498a5
config: break mergeURLPath into a separate module 2025-02-15 16:51:21 -06:00
Alex Gleason
5f6cdaf7d5
config: refactor schemas into a separate file 2025-02-15 16:37:33 -06:00
Alex Gleason
1636601bfe
config: crypto.ts -> utils/crypto.ts 2025-02-15 16:32:10 -06:00
Alex Gleason
cbe156ae2b
Create @ditto/config module 2025-02-15 16:28:26 -06:00
Alex Gleason
482b0092da Merge branch 'monorepo' into 'main'
Make Ditto a monorepo

See merge request soapbox-pub/ditto!661
2025-02-15 20:47:36 +00:00
Alex Gleason
2ccd4bad96
Move static/ into packages/ditto 2025-02-15 14:41:57 -06:00
Alex Gleason
5ee682ef8f
Remove accidental file: log.json 2025-02-15 14:38:15 -06:00
Alex Gleason
3476f45b41
Add @ditto/ditto as a workspace package 2025-02-15 14:31:30 -06:00
Alex Gleason
aa8bb03e5a
mv src packages/ditto 2025-02-15 14:21:05 -06:00
Alex Gleason
5bf6865f21 Merge branch 'notify-replaceable' into 'main'
NOTIFY when replaceable events update

See merge request soapbox-pub/ditto!660
2025-02-15 19:16:27 +00:00
Alex Gleason
d8d8cc20c9
NOTIFY when replaceable events update 2025-02-15 13:09:29 -06:00
Alex Gleason
6eb579e137 Merge branch 'cashu-test-pipeline-fast' into 'main'
Cashu test pipeline fast

See merge request soapbox-pub/ditto!659
2025-02-14 18:14:14 +00:00
P. Reis
31eb74b6e4 refactor: use mockFetch 2025-02-14 14:47:20 -03:00
P. Reis
028d41d585 refactor: use fetch mock 2025-02-14 11:52:37 -03:00
P. Reis
cb475f1126 dependency: add jsr:@std/testing/mock 2025-02-14 11:51:36 -03:00
P. Reis
9e7576f248 deno.lock: types/node 2025-02-14 11:36:26 -03:00
P. Reis
461feff952 fix: make cashu tests faster by giving invalid URL 2025-02-14 11:35:12 -03:00
P. Reis
ad967bbb5d Revert "Delete cashu.test.ts"
This reverts commit 032b29cfba.
2025-02-14 10:46:59 -03:00
Alex Gleason
032b29cfba
Delete cashu.test.ts 2025-02-13 21:34:10 -06:00
Alex Gleason
8d19eb3ec6
Don't hydrate related events when posting a status 2025-02-13 21:33:34 -06:00
Alex Gleason
64c703cef4
Log ip in relay 2025-02-13 21:11:59 -06:00
Alex Gleason
24ee33489d Merge branch 'trigger-insert' into 'main'
Trigger NOTIFY only on insert (not update)

See merge request soapbox-pub/ditto!658
2025-02-14 02:48:49 +00:00
Alex Gleason
dd336232d5
Trigger NOTIFY only on insert (not update) 2025-02-13 20:45:02 -06:00
Alex Gleason
053c362d44 Merge branch 'deno-2.1.10' into 'main'
Upgrade Deno to v2.1.10

See merge request soapbox-pub/ditto!657
2025-02-14 00:21:06 +00:00
Alex Gleason
b07ba9423b
Remove png-to-ico (this augments @types/node to a wrong version) 2025-02-13 18:16:52 -06:00
Alex Gleason
30b4900992
Upgrade Deno to v2.1.10 2025-02-13 17:46:28 -06:00
Alex Gleason
dda1bebfbc Merge branch 'cleanup' into 'main'
Cleanup

See merge request soapbox-pub/ditto!656
2025-02-13 23:45:26 +00:00
Alex Gleason
a2de8cdf82
Remove unnecessary lint rules from deno.json, avoid explicit any 2025-02-13 17:41:30 -06:00
Alex Gleason
359558e2d6
Remove unused docs and ansible directories 2025-02-13 17:21:33 -06:00
Alex Gleason
efb91d9f3f Merge branch 'cashu' into 'main'
Swap the tokens into the wallet

See merge request soapbox-pub/ditto!636
2025-02-13 22:54:54 +00:00
P. Reis
a5d4906257 refactor: just ignore leaky tests 2025-02-13 19:51:13 -03:00
Alex Gleason
26346b83ac
Fix leaky tests, but nutzapMiddleware is still broken 2025-02-13 15:47:53 -06:00
P. Reis
6473ab0f98 Merge branch 'main' into cashu 2025-02-13 13:25:06 -03:00
P. Reis
3418871a70 feat: create GET '/api/v1/ditto/cashu/mints' endpoint 2025-02-13 13:23:47 -03:00
Alex Gleason
00146dc192 Merge branch 'search-pagination' into 'main'
Try using offset pagination for account search

See merge request soapbox-pub/ditto!655
2025-02-13 05:41:22 +00:00
Alex Gleason
3c0e6dac76
Try using offset pagination for account search 2025-02-12 23:35:43 -06:00
Alex Gleason
a85daf1e67
EventsDB: fix domain query test 2025-02-12 23:11:09 -06:00
Alex Gleason
aabb20efa3
Rework domain queries so allow querying all subdomains by base domain 2025-02-12 23:04:08 -06:00
Alex Gleason
d991464810
Fix domain feeds 2025-02-12 22:45:53 -06:00
P. Reis
795c83ee88 refactor: remove unused imports and get rid of useless await 2025-02-12 20:28:34 -03:00
P. Reis
7d2258ff50 refactor: delete old controllers code: swapNutzapsToWalletController, createNutzapInformationController and createCashuWalletController 2025-02-12 20:11:02 -03:00
Alex Gleason
9ca0b2d21c Merge branch 'search-perf' into 'main'
Improve performance of account search

See merge request soapbox-pub/ditto!653
2025-02-12 22:21:24 +00:00
Alex Gleason
db793a3c6c
Refresh materialized view in search test 2025-02-12 16:20:04 -06:00
Alex Gleason
1482ee148e
Add missing indexes, fix order of results 2025-02-12 16:13:44 -06:00
Alex Gleason
ab7a0e06c7
Add a top_authors materialized view 2025-02-12 15:21:09 -06:00
Alex Gleason
510ad647be
Fix type errors 2025-02-12 15:02:19 -06:00
Alex Gleason
5969d9b3fa
getPubkeysBySearch: reduce limit of second query if applicable 2025-02-12 14:47:20 -06:00
Alex Gleason
379953a8cb
Improve performance of account search 2025-02-12 14:40:00 -06:00
P. Reis
96a16a9fd0 feat: create GET '/api/v1/ditto/cashu/mints' endpoint 2025-02-12 16:33:56 -03:00
Alex Gleason
7d8e5e676c Merge branch 'legacy-media' into 'main'
Enable media:true for legacy (non-imeta) URL attachments

See merge request soapbox-pub/ditto!652
2025-02-12 19:23:15 +00:00
Alex Gleason
112081e4bb
Enable media:true for legacy (non-imeta) URL attachments 2025-02-12 13:21:04 -06:00
P. Reis
7095519198 chore: remove done comments 2025-02-12 13:46:37 -03:00
Alex Gleason
8d76ab2906 Merge branch 'rm-pubkey-domains' into 'main'
Remove pubkey_domains table

See merge request soapbox-pub/ditto!651
2025-02-12 03:51:52 +00:00
Alex Gleason
f6fe777e78
Remove pubkey_domains table 2025-02-11 21:49:58 -06:00
Alex Gleason
efbefd918a
Speed up db:populate-extensions task 2025-02-11 21:20:16 -06:00
P. Reis
03946fabc8 test: GET /wallet must be successful 2025-02-11 22:11:06 -03:00
P. Reis
5e86844c12 feat: craete GET '/api/v1/ditto/cashu/wallet' endpoint
refactor: remove old swap controller and create swapNutzapsMiddleware
2025-02-11 22:10:33 -03:00
Alex Gleason
173aea6458
Update deno.lock 2025-02-11 18:17:22 -06:00
Alex Gleason
266fa08004 Merge branch 'negative-search' into 'main'
Upgrade Nostrify to support negative search queries, remove getIdsBySearch function

See merge request soapbox-pub/ditto!650
2025-02-12 00:16:19 +00:00
Alex Gleason
c379c11b25
search: support pagination via Link header 2025-02-11 18:13:47 -06:00
Alex Gleason
eb94da6cca
Upgrade Nostrify to support negative search queries, remove getIdsBySearch function 2025-02-11 17:40:28 -06:00
Alex Gleason
f8777b9e09 Merge branch 'fix-language' into 'main'
Ensure `.language` property gets added to DittoEvent when it's queried

See merge request soapbox-pub/ditto!649
2025-02-11 19:23:51 +00:00
Alex Gleason
43d675b837
Ensure .language property gets added to DittoEvent when it's queried 2025-02-11 13:19:32 -06:00
P. Reis
76f91687bd test: split test into 2 test functions 2025-02-11 12:58:02 -03:00
P. Reis
edd9512b01 test: PUT '/api/v1/ditto/cashu/wallet' endpoint must NOT be successful 2025-02-11 11:45:14 -03:00
P. Reis
89840eb279 refactor: create walletSchema and use it where required 2025-02-11 11:29:58 -03:00
P. Reis
1ff6511b39 test: PUT '/api/v1/ditto/cashu/wallet' endpoint 2025-02-11 11:07:46 -03:00
P. Reis
b74a0ffac0 refactor: create NIP-60 wallet and NIP-61 nutzap information event in the same endpoint 2025-02-11 10:59:04 -03:00
Alex Gleason
207e04ef08
Prewarm card cache in pipeline 2025-02-10 22:19:35 -06:00
Alex Gleason
756a9d9607
favicon: image/x-icon is an acceptable mime type 2025-02-10 21:21:18 -06:00
Alex Gleason
e468072b55 Merge branch 'home-filters' into 'main'
homeTimelineController: support exclude_replies, only_media params

See merge request soapbox-pub/ditto!648
2025-02-10 23:10:22 +00:00
Alex Gleason
11adaef243
homeTimelineController: support exclude_replies, only_media params 2025-02-10 17:08:29 -06:00
Alex Gleason
9e7aeda364 Merge branch 'exclude-replies-index' into 'main'
accountStatusesController: handle exclude_replies with NIP-50 search ext

See merge request soapbox-pub/ditto!647
2025-02-10 23:01:39 +00:00
Alex Gleason
8a9928696b
accountStatusesController: handle exclude_replies with NIP-50 search ext 2025-02-10 16:56:59 -06:00
Alex Gleason
c9dc3b198c Merge branch 'nip11-cors' into 'main'
Set CORS header on NIP-11 response

See merge request soapbox-pub/ditto!646
2025-02-10 22:24:27 +00:00
Alex Gleason
8e3976ea78 Merge branch 'hydrate-batch' into 'main'
hydrate: batch queries together

See merge request soapbox-pub/ditto!645
2025-02-10 22:23:49 +00:00
Alex Gleason
56c782e6e5
Set CORS header on NIP-11 response 2025-02-10 16:22:56 -06:00
Alex Gleason
4e86b6bf3f
hydrate: quotes must be gathered in a separate step 2025-02-10 16:21:01 -06:00
Alex Gleason
8267c170f0
hydrate: batch queries together 2025-02-10 16:15:13 -06:00
P. Reis
5076cdcc33 Merge branch 'main' into cashu 2025-02-10 17:18:40 -03:00
Alex Gleason
425edf2174
Add controller test, refactor some middlewares 2025-02-10 12:41:41 -06:00
Alex Gleason
1368304d25
Add cashuApp (rough draft) 2025-02-10 12:04:46 -06:00
P. Reis
00d10c7f9b refactor: TODO comments 2025-02-10 13:24:19 -03:00
Alex Gleason
1c4f0a87d5 Merge branch 'index-u-tags' into 'main'
feat: index 'u' tags

See merge request soapbox-pub/ditto!644
2025-02-10 16:04:50 +00:00
P. Reis
5a19a35847 Merge branch 'main' into cashu
Conflicts:
	deno.json
2025-02-10 12:48:55 -03:00
P. Reis
f85e7f7c33 feat: index 'u' tags 2025-02-09 21:27:38 -03:00
Alex Gleason
424272c97b Merge branch 'nip05-db' into 'main'
Store NIP-05 in the database

See merge request soapbox-pub/ditto!641
2025-02-09 23:46:50 +00:00
Alex Gleason
16f3a13364
SimpleLRU: respect AbortSignal 2025-02-09 17:22:53 -06:00
Alex Gleason
a597eae674
Merge remote-tracking branch 'origin/main' into nip05-db 2025-02-09 15:11:20 -06:00
Alex Gleason
8db0238c9a Merge branch 'asyncutil' into 'main'
@lambdalisue/async -> @core/asyncutil

See merge request soapbox-pub/ditto!643
2025-02-09 21:07:40 +00:00
Alex Gleason
433c2a4347
@lambdalisue/async -> @core/asyncutil 2025-02-09 15:06:13 -06:00
Alex Gleason
56e478a65d Merge branch 'rm-fetch-worker' into 'main'
Remove fetchWorker

See merge request soapbox-pub/ditto!642
2025-02-09 21:04:24 +00:00
Alex Gleason
838f773b84
Remove fetchWorker 2025-02-09 15:02:15 -06:00
Alex Gleason
a98bfdd0c6
fetchWorker: try throwing a preemptive AbortError inside the worker itself 2025-02-09 14:52:43 -06:00
Alex Gleason
93874df063
fetchWorker: log responses 2025-02-09 14:50:28 -06:00
Alex Gleason
576a66460f
fetchWorker: preemptively throw if signal is aborted 2025-02-09 14:45:26 -06:00
Alex Gleason
ebbde66824
Add @core/asyncutil 2025-02-09 14:34:12 -06:00
Alex Gleason
41419e84dc
Refetch nip05 if last_verified is null 2025-02-09 14:20:32 -06:00
Alex Gleason
8386fe7609
try-catch favicon fetch 2025-02-09 13:32:47 -06:00
Alex Gleason
dd009de5be
Wrap nip05 updates in a try-catch 2025-02-09 13:31:17 -06:00
Alex Gleason
8c60a4842b
Fix NIP05 verification 2025-02-09 13:27:05 -06:00
Alex Gleason
48507b7505
faviconCache: check favicon.ico explicitly 2025-02-09 11:57:09 -06:00
P. Reis
cde091132e fix: remove comment 2025-02-09 11:54:12 -03:00
Alex Gleason
e7027af1ae
Fix hydrating mentions 2025-02-08 10:13:38 -06:00
Alex Gleason
b8c67a85d0
hydrate: move gatherMentions down 2025-02-08 09:58:02 -06:00
P. Reis
efceee505a fix: pass privkey to cashuWallet.receive 2025-02-07 23:49:57 -03:00
P. Reis
361ef9a600 fix: stop trying to decrypt kind 7376 content (lol), log errors 2025-02-07 23:32:21 -03:00
P. Reis
55cc109376 Merge branch 'main' into cashu 2025-02-07 22:53:34 -03:00
P. Reis
f9da100936 refactor(swapNutzapsToWalletController): change to POST method 2025-02-07 22:41:39 -03:00
Alex Gleason
5811a19151
Fix mentions in statuses? 2025-02-07 19:05:37 -06:00
Alex Gleason
7780507a15
Add semaphore to nip05 script 2025-02-07 18:17:50 -06:00
Alex Gleason
b902abc7cc
Use an even simpler query for db:populate:nip05 script 2025-02-07 18:13:39 -06:00
Alex Gleason
b0dc7faaff
Simplify db:populate:nip05 script 2025-02-07 17:49:39 -06:00
Alex Gleason
a4a26d7575
Make db:populate:nip05 script more efficient 2025-02-07 17:48:07 -06:00
Alex Gleason
5157a90b63
Add populate:nip05 script 2025-02-07 16:03:22 -06:00
Alex Gleason
93141c1db1
Hook everything up? (In a messy way) 2025-02-07 15:39:25 -06:00
P. Reis
a6c7bbd751 createNutzapInformationController: add TODO message 2025-02-07 18:11:39 -03:00
Alex Gleason
d9b0bc1437
Add nip05 and favicon results to the database, make renderAccount synchronous 2025-02-07 13:39:56 -06:00
Alex Gleason
af262b5d52
Whoops, fix streak days calculation 2025-02-07 12:06:34 -06:00
Alex Gleason
c476596d0a Merge branch 'streak-window' into 'main'
Make STREAK_WINDOW configurable

See merge request soapbox-pub/ditto!640
2025-02-07 17:56:36 +00:00
Alex Gleason
ea8ef09045
Change default streak window to 36 hours 2025-02-07 11:54:47 -06:00
Alex Gleason
46558a97e4
Make STREAK_WINDOW configurable 2025-02-07 11:50:37 -06:00
Alex Gleason
00e10eb19f
detectLanguage: strip numbers from text before matching language patterns 2025-02-06 18:42:29 -06:00
Alex Gleason
86ffa7f0cc
Don't display broken streak through the API 2025-02-06 16:33:14 -06:00
Alex Gleason
30559ba043
streak-recompute: only update changed rows 2025-02-06 16:04:25 -06:00
Alex Gleason
08a5e7f761 Merge branch 'streak2' into 'main'
Streak API: Version 2

See merge request soapbox-pub/ditto!639
2025-02-06 22:01:47 +00:00
Alex Gleason
b480947c4d
Add a script to recompute the streak of all authors 2025-02-06 15:56:49 -06:00
Alex Gleason
080c34d13f
Fix streak broken logic 2025-02-06 14:53:42 -06:00
Alex Gleason
abea4f17b3
Streak: report a 1 day streak after the first post 2025-02-06 14:44:01 -06:00
Alex Gleason
084df2b59d
Streaks API 2025-02-06 14:26:08 -06:00
Alex Gleason
c2aab97018
indexExtensions: ensure kind 6 has reply:false to test the performance difference between -reply:true 2025-02-06 11:24:49 -06:00
Alex Gleason
f412a0ae50
detectLanguage: test that a Japanese text with Han-only characters is ambiguous 2025-02-06 10:40:41 -06:00
P. Reis
f5ebb5d82a Merge branch 'main' into cashu 2025-02-06 13:19:35 -03:00
P. Reis
f7e49cd5ec checkpoint: implement nutzap redemption history (kind 7376) 2025-02-06 12:28:09 -03:00
Alex Gleason
c5680150e6
Copy the code into getIdsBySearch >:( 2025-02-05 22:56:02 -06:00
Alex Gleason
6cf5d42a5b
Upgrade Nostrify to enable negative search tokens 2025-02-05 22:53:26 -06:00
P. Reis
d61f0d1d4b checkpoint: swap tokens into user controlled wallet
TODO: create the 7376 history kind, reemded marker, etc
2025-02-05 23:34:56 -03:00
P. Reis
df1a3fe842 dependency: add cashu-ts 2025-02-05 19:32:48 -03:00
Alex Gleason
c837330b62 Merge branch 'language-code' into 'main'
Upgrade npm:iso-639-1, remove LanguageCode type assertions

See merge request soapbox-pub/ditto!637
2025-02-05 16:36:54 +00:00
Alex Gleason
7f5bfc6834
Upgrade npm:iso-639-1, remove LanguageCode type assertions 2025-02-05 10:22:09 -06:00
P. Reis
2012ef5192 Merge branch 'main' into cashu 2025-02-04 21:35:41 -03:00
P. Reis
870847127b checkpoint: implement swapNutzapsToWalletController 2025-02-04 21:33:02 -03:00
Alex Gleason
e58d0af691 Merge branch 'definitive-languages' into 'main'
detectLanguage: check the text's script for definitive language categorization for some languages

See merge request soapbox-pub/ditto!635
2025-02-04 21:26:12 +00:00
Alex Gleason
2f2cb2c4fc
detectLanguage: check the text's script for definitive language categorization for some languages 2025-02-04 15:05:52 -06:00
P. Reis
236a9284ca refactor(createNutzapInformationController): implement new NIP 60 cashu wallet 2025-02-04 15:12:56 -03:00
P. Reis
e9696b8a2a refactor(createCashuWalletController): implement new NIP 60 cashu wallet 2025-02-04 12:48:56 -03:00
P. Reis
daedf24ca8 fix: add missing endpoint createNutzapInformationController 2025-02-04 12:34:41 -03:00
Alex Gleason
47d004d92a Merge branch 'add-script-populate-gallery' into 'main'
feat: populate extensions

See merge request soapbox-pub/ditto!634
2025-02-03 23:08:20 +00:00
P. Reis
7beb2d594a feat: populate extensions 2025-02-03 23:08:20 +00:00
Alex Gleason
ec5a000265
Upgrade gleasonator-policy, only index lowercase t-tags in EventsDB 2025-02-03 16:58:26 -06:00
Alex Gleason
1bfd5f992d Merge branch 'mention-npub-fix' into 'main'
Only parse mentions with valid pubkeys

Closes #290

See merge request soapbox-pub/ditto!633
2025-02-03 20:55:45 +00:00
Alex Gleason
cfa6848927
Only parse mentions with valid pubkeys
Fixes https://gitlab.com/soapbox-pub/ditto/-/issues/290
2025-02-03 14:53:38 -06:00
Alex Gleason
00953e4a0a Merge branch 'feat-nutzap-information' into 'main'
feat: create and implement createNutzapInformationController

See merge request soapbox-pub/ditto!630
2025-02-03 15:54:22 +00:00
Alex Gleason
41e974c31c
getIdsBySearch: AND and OR logic 2025-02-02 22:00:28 -06:00
Alex Gleason
116b675664
Tag protocol from proxy tag 2025-02-02 21:44:08 -06:00
Alex Gleason
70f8698e33
Upgrade @nostrify/db to v0.37.2 2025-02-02 21:41:35 -06:00
Alex Gleason
ffe49b3648
getIdsBySearch: fix joining txt tokens 2025-02-02 21:39:49 -06:00
Alex Gleason
0d718e28b4
Update getIdsBySearch to use the new search extensions column 2025-02-02 21:26:58 -06:00
Alex Gleason
4664aefa55
Remove the language column from the database, drop the default on search_ext 2025-02-02 21:06:30 -06:00
Alex Gleason
3edddb8dcc
Upgrade @nostrify/db 2025-02-02 20:40:36 -06:00
Alex Gleason
8693dd0e5d
Coerce only_media to a boolean again 2025-02-02 20:23:38 -06:00
Alex Gleason
83347df845
Fix video tag being incorrectly applied 2025-02-02 20:14:30 -06:00
Alex Gleason
3d221aa357 Merge branch 'feat-search-mime-type' into 'main'
feat: add mime_type column in nostr_events, add the NIP 50 search extensions: exact_mime_type, partial_mime_type, only_media

See merge request soapbox-pub/ditto!623
2025-02-03 01:46:54 +00:00
Alex Gleason
ad68946899
Fix defaultTo migration 2025-02-02 19:41:45 -06:00
Alex Gleason
f04ca2b6ff
Rework language and media columns to use Nostrify search_ext column 2025-02-02 19:32:43 -06:00
Alex Gleason
baad8821f5
Upgrade @nostrify/db 2025-02-02 17:47:34 -06:00
Alex Gleason
b4184631c3
Merge remote-tracking branch 'origin/main' into feat-search-mime-type 2025-02-02 17:47:10 -06:00
Alex Gleason
640e533dca
Add InternalRelay test 2025-02-01 11:59:38 -06:00
Alex Gleason
b7a1efe33c
localSuggestionsController: skip accounts without a profile 2025-01-30 21:56:45 -06:00
Alex Gleason
2dfde337cd
Fix localSuggestionsController 2025-01-30 21:53:45 -06:00
Alex Gleason
7f71f6f50c Merge branch 'local-suggested' into 'main'
Add local suggestions controller

See merge request soapbox-pub/ditto!631
2025-01-31 03:19:35 +00:00
Alex Gleason
99d52f8640
Add local suggestions controller 2025-01-30 21:16:38 -06:00
Alex Gleason
c3403ba724
Make AppController accept a path parameter 2025-01-30 21:03:42 -06:00
Alex Gleason
c83a2dba7e
Give requireSigner middleware the right type 2025-01-30 20:39:51 -06:00
P. Reis
8797963d8c refactor: remote import at the top 2025-01-30 20:35:46 -03:00
P. Reis
db6ac74702 feat: create and implement createNutzapInformationController 2025-01-30 20:26:24 -03:00
Alex Gleason
9ced9fb31d Merge branch 'cashu-wallet' into 'main'
feat: endpoint for creating NIP-60 wallet

Closes #289

See merge request soapbox-pub/ditto!629
2025-01-30 18:59:11 +00:00
P. Reis
6a34f8f6e5 fix: use zod array instead of zod set
https://github.com/colinhacks/zod/issues/3963
2025-01-30 11:07:15 -03:00
Alex Gleason
c6848b9ce2
Log events sent to our relay 2025-01-30 02:33:19 -06:00
Alex Gleason
2ac2a45350
Actually do log traces 2025-01-30 02:23:47 -06:00
Alex Gleason
38f5a12284
Log relay communication 2025-01-30 02:19:19 -06:00
Alex Gleason
b473898cef
Upgrade Logi 2025-01-30 01:43:57 -06:00
P. Reis
d19b925db0 fix: get first event from query 2025-01-29 20:44:34 -03:00
P. Reis
d5ff66a542 feat: endpoint for creating NIP-60 wallet 2025-01-29 20:41:22 -03:00
Alex Gleason
8f4ae833ca
logi: message -> msg 2025-01-29 12:30:46 -06:00
Alex Gleason
449daf1e35
ditto.http.response: use error level when status >= 500 2025-01-29 10:06:21 -06:00
Alex Gleason
5f99bddb42
Add a logi custom handler for serializing non-JSON stuff (fix sql parameter serialization) 2025-01-28 19:37:45 -06:00
Alex Gleason
49735ce1fe
InstanceV2: bump max_media_attachments to 20 2025-01-28 14:57:32 -06:00
Alex Gleason
e31c58ac46 Merge branch 'last-kind7' into 'main'
EventsDB: index only the final `e` and `p` tag of kind 7 events

Closes #220

See merge request soapbox-pub/ditto!628
2025-01-28 20:24:23 +00:00
Alex Gleason
c7264d7627
Fix trends test 2025-01-28 14:22:16 -06:00
Alex Gleason
cce693dc9b
EventsDB: index only the final e and p tag of kind 7 events
Fixes https://gitlab.com/soapbox-pub/ditto/-/issues/220
2025-01-28 14:11:08 -06:00
Alex Gleason
55b338adea Merge branch 'ipwhitelist' into 'main'
Add IP_WHITELIST variable to bypass rate limiting

See merge request soapbox-pub/ditto!627
2025-01-28 17:41:44 +00:00
Alex Gleason
8deea54ec8
Add IP_WHITELIST variable to bypass rate limiting 2025-01-28 11:40:16 -06:00
Alex Gleason
7a2a6e00c1
Upgrade Logi 2025-01-27 21:38:11 -06:00
Alex Gleason
fd553d98e2
KyselyLogger: fix import order 2025-01-27 19:26:52 -06:00
Alex Gleason
5ea33f6817
KyselyLogger: improve parameter serialization 2025-01-27 19:26:26 -06:00
Alex Gleason
05c90fb677 Merge branch 'logi' into 'main'
Switch to JSON logging

See merge request soapbox-pub/ditto!626
2025-01-28 00:15:58 +00:00
Alex Gleason
78cde6dcb2
Fix import order in api/admin 2025-01-27 18:14:12 -06:00
Alex Gleason
d23990e709
Remove unused variable 2025-01-27 18:13:29 -06:00
Alex Gleason
2165e649bc
Remove Stickynotes, replace all occurrences of console.log with logi 2025-01-27 18:11:32 -06:00
Alex Gleason
2a6f954df1
Add logi, start using it in KyselyLogger 2025-01-27 15:49:43 -06:00
Alex Gleason
224d7bfef9
Add SyslogIdentifier=ditto to systemd unit 2025-01-27 11:27:57 -06:00
Alex Gleason
452088386c
Upgrade @nostrify/db 2025-01-25 17:53:38 -06:00
Alex Gleason
85d9e210d3 Merge branch 'limiter' into 'main'
relay: stricter rate limits

See merge request soapbox-pub/ditto!625
2025-01-25 21:45:06 +00:00
Alex Gleason
7601cfa430
Don't throw inside the websocket callbacks because that crashes the whole application 2025-01-25 15:37:09 -06:00
Alex Gleason
fd312032a4
MultiRateLimiter: ensure the active limiter is used for ratelimit values 2025-01-25 15:31:49 -06:00
Alex Gleason
43a47770f4
relay: stricter rate limits 2025-01-25 15:21:16 -06:00
Alex Gleason
68a0ef6648
Add ratelimiter tests 2025-01-25 15:20:52 -06:00
Alex Gleason
12de164a4f
Add a custom RateLimiter implementation 2025-01-25 13:36:49 -06:00
Alex Gleason
b8d288868d
Turn on NOTIFY_ENABLED by default (now that it's optimized) 2025-01-25 01:46:31 -06:00
Alex Gleason
a8b8b8b427
Reduce default FIREHOSE_CONCURRENCY to 1 2025-01-25 01:46:08 -06:00
Alex Gleason
75be90694c
Always inject og metadata, but add generous cache headers 2025-01-25 01:42:20 -06:00
Alex Gleason
5dc840e14e
Avoid applying ratelimit to /packs 2025-01-24 04:27:56 -06:00
Alex Gleason
218604aa56
Move ratelimitMiddleware below metricsMiddleware, try adding a stricter ratelimit 2025-01-23 22:43:54 -06:00
Alex Gleason
64370c23e3
caddy: remove unnecessary hsts header 2025-01-23 15:42:19 -06:00
Alex Gleason
8083148d03
Don't include ratelimit headers on the default bucket 2025-01-23 15:27:24 -06:00
Alex Gleason
3fdd6e2213
Force no-store header on server error and rate limit responses 2025-01-23 15:23:48 -06:00
Alex Gleason
afa0a337d3
Add a default cache-control header of no-store 2025-01-23 14:59:29 -06:00
Alex Gleason
cd2619dbf3 Merge branch 'cache-control' into 'main'
Add Cache-Control headers

See merge request soapbox-pub/ditto!624
2025-01-23 20:15:56 +00:00
Alex Gleason
871222ee4e
Add Cache-Control headers to a bunch of routes 2025-01-23 14:11:10 -06:00
Alex Gleason
66f7853c3b
Add cacheControlMiddleware 2025-01-23 13:04:40 -06:00
Alex Gleason
b8dbc432ab
Add Cache-Control headers to nostr.json responses 2025-01-23 13:00:43 -06:00
Alex Gleason
aa1515e7e9
Remove accidental HSTS header from packs/ route 2025-01-23 13:00:11 -06:00
P. Reis
a7bb975221 fix(migration 042): use .ifExists() 2025-01-22 20:30:39 -03:00
P. Reis
f879315d34 feat: script to populate mime-type 2025-01-22 20:25:40 -03:00
P. Reis
e388925815 Merge branch 'main' into feat-search-mime-type 2025-01-22 17:11:03 -03:00
P. Reis
c3966be65b feat(accountStatusesController): query for media faster 2025-01-22 17:10:24 -03:00
P. Reis
b037be44a4 feat: add mime_type column in nostr_events, add the following NIP 50 search extensions:
exact_mime_type, example: 'exact_mime_type:image/png' (uses hash index)
partial_mime_type, example 'partial_mime_type:image' (uses b-tree index)
only_media, example 'only_media:true' (sometimes uses index)
2025-01-22 17:01:10 -03:00
Alex Gleason
6d31949944
notActivitypubMiddleware: add bare ld+json to ACTIVITYPUB_TYPES 2025-01-21 18:49:08 -06:00
Alex Gleason
420cbba71f Merge branch 'not-activitypub' into 'main'
Add notActivityPub middleware to stop AP requests on /users/*

See merge request soapbox-pub/ditto!622
2025-01-22 00:43:18 +00:00
Alex Gleason
281872b0ad
Add notActivityPub middleware to stop AP requests on /users/* 2025-01-21 18:41:04 -06:00
Alex Gleason
3fd311b929 Merge branch 'pipeline-source' into 'main'
pipeline: skip refetch of encountered events

See merge request soapbox-pub/ditto!620
2025-01-22 00:03:27 +00:00
Alex Gleason
7fdfb806f4
pipeline: skip refetch of encountered events 2025-01-21 17:31:55 -06:00
Alex Gleason
1204dc722f Merge branch 'fix-mention' into 'main'
fix: mention with hyphen

See merge request soapbox-pub/ditto!619
2025-01-21 16:16:28 +00:00
P. Reis
e89853c56d fix: mention with hyphen 2025-01-21 13:12:39 -03:00
Alex Gleason
93a035e3ff
Streaming: handle token errors as 401s 2025-01-20 22:47:21 -06:00
Alex Gleason
ba8b7ecaea Merge branch 'caddy-log-ratelimit' into 'main'
Caddyfile: enable access log, add X-Real-IP header for rate limiting

See merge request soapbox-pub/ditto!618
2025-01-18 19:14:47 +00:00
Alex Gleason
d368bf90d5
Caddyfile: enable access log, add X-Real-IP header for rate limiting 2025-01-18 13:13:22 -06:00
Alex Gleason
f2766842ef Merge branch 'caddyfile' into 'main'
Add a Caddyfile

See merge request soapbox-pub/ditto!617
2025-01-18 01:00:54 +00:00
Alex Gleason
5b9868bc3a
Add a Caddyfile
Related: https://gitlab.com/soapbox-pub/ditto/-/issues/265
2025-01-17 18:59:25 -06:00
Alex Gleason
ed29ecdb3f Merge branch 'packs-cache' into 'main'
Add cache-control headers to /packs/*

See merge request soapbox-pub/ditto!616
2025-01-18 00:21:26 +00:00
Alex Gleason
51981009c4
Add cache-control headers to /packs/* 2025-01-17 18:19:32 -06:00
Alex Gleason
1e53457c9d Merge branch 'kind-20' into 'main'
Support kind 20 "Picture" events (NIP-68)

See merge request soapbox-pub/ditto!615
2025-01-05 17:39:35 +00:00
Alex Gleason
b61eb2ff11
Fix favourites of kind 20 events 2025-01-05 11:37:38 -06:00
Alex Gleason
079177ea0b
EventsDB: index kind 20 in search the same as kind 1 2025-01-05 11:26:05 -06:00
Alex Gleason
7a60b4b8d8
Support kind 20 "Picture" events (NIP-68) 2025-01-05 11:23:18 -06:00
Alex Gleason
5a32964eb5 Merge branch 'upgrade-nostrify' into 'main'
Upgrade Nostrify

See merge request soapbox-pub/ditto!614
2024-12-30 20:31:20 +00:00
Alex Gleason
e523da9d19
Upgrade Nostrify 2024-12-30 14:29:45 -06:00
Alex Gleason
51fc0c9cc9 Merge branch 'tl-ratelimit' into 'main'
Stricter timeline rate limits

See merge request soapbox-pub/ditto!612
2024-12-27 19:20:29 +00:00
Alex Gleason
b85513496c
Ratelimit follow and unfollow 2024-12-27 13:18:22 -06:00
Alex Gleason
54c398c5fa
Ratelimit /followers and /following endpoints 2024-12-27 13:16:33 -06:00
Alex Gleason
a316e92001
Bump limits slightly, also limit account statuses controller 2024-12-27 13:15:47 -06:00
Alex Gleason
eb10cdce76
Stricter timeline rate limits 2024-12-27 13:06:32 -06:00
Alex Gleason
e32976945e Merge branch 'media-newlines' into 'main'
Stop adding unnecessary newlines to the top of posts with images only

See merge request soapbox-pub/ditto!611
2024-12-27 02:43:20 +00:00
Alex Gleason
79e87008c1
Move content back up because it has side-effects with pubkeys 2024-12-26 20:40:59 -06:00
Alex Gleason
f72fdf79bb
Stop adding unnecessary newlines to the top of posts with images only 2024-12-26 20:33:26 -06:00
Alex Gleason
bb50ad7a43 Merge branch 'bunker-44' into 'main'
Switch to NIP-44 bunker encryption

See merge request soapbox-pub/ditto!608
2024-12-18 08:00:07 +00:00
Alex Gleason
139e600b79
Switch to NIP-44 bunker encryption
https://gitlab.com/soapbox-pub/ditto/-/issues/279
2024-12-18 01:56:53 -06:00
Alex Gleason
75f9c90a8c Merge branch 'future-block' into 'main'
pipeline: block events too far in the future

See merge request soapbox-pub/ditto!607
2024-12-17 21:07:18 +00:00
Alex Gleason
e3294e5351
pipeline: block events too far in the future 2024-12-17 14:58:40 -06:00
Alex Gleason
f1f00fcf38 Merge branch 'fix-reaction-target-pubkey' into 'main'
fix: add 'p' tag to kind 7 event

See merge request soapbox-pub/ditto!606
2024-12-12 00:06:46 +00:00
P. Reis
5de7cfb4da fix: add 'p' tag to kind 7 event 2024-12-11 21:04:00 -03:00
Alex Gleason
6eaf18a890 Merge branch 'valid-ws' into 'main'
Filter out invalid WebSocket URLs from pool, prevent admins from setting them

Closes #276

See merge request soapbox-pub/ditto!605
2024-12-10 23:45:58 +00:00
Alex Gleason
f8e77d90eb
Filter out invalid WebSocket URLs from pool, prevent admins from setting them
Fixes https://gitlab.com/soapbox-pub/ditto/-/issues/276
2024-12-10 17:43:41 -06:00
Alex Gleason
e3cc6922ae Merge branch 'make-search-domain-faster' into 'main'
Make domain:<domain> search faster

See merge request soapbox-pub/ditto!604
2024-12-09 14:49:18 +00:00
P. Reis
8101483622 refactor: make domain:<domain> search faster 2024-12-09 11:32:51 -03:00
Alex Gleason
dbfd1a9d35 Merge branch 'self-label' into 'main'
Fix Bluesky's selfLabel name

See merge request soapbox-pub/ditto!602
2024-12-06 20:52:13 +00:00
Alex Gleason
a7bfc665c3
Fix Bluesky's selfLabel name 2024-12-06 14:50:16 -06:00
Alex Gleason
d0f53f5601 Merge branch 'fix-do-not-search-when-empty-content' into 'main'
refactor(getIdsBySearch): do not search if the search content is empty

See merge request soapbox-pub/ditto!599
2024-12-05 19:24:54 +00:00
Alex Gleason
5df47403ad Merge branch 'fix-captcha-showing-up' into 'main'
Revert "Merge branch 'revert-70d30887' into 'main'"

Closes #269

See merge request soapbox-pub/ditto!601
2024-12-03 23:24:59 +00:00
P. Reis
b5221eb43a fix: stop captcha showing up 2024-12-03 20:05:38 -03:00
P. Reis
e0d9e83f28 Revert "Merge branch 'revert-70d30887' into 'main'"
This reverts commit 0c2f082281, reversing
changes made to 70d3088735.
2024-12-03 20:04:18 -03:00
Alex Gleason
0c2f082281 Merge branch 'revert-70d30887' into 'main'
Revert "Merge branch 'fix-stop-overwite-kind-0-unnecessarily' into 'main'"

See merge request soapbox-pub/ditto!600
2024-12-03 22:04:10 +00:00
Alex Gleason
261cd339fa Revert "Merge branch 'fix-stop-overwite-kind-0-unnecessarily' into 'main'"
This reverts merge request !598
2024-12-03 22:03:46 +00:00
Alex Gleason
70d3088735 Merge branch 'fix-stop-overwite-kind-0-unnecessarily' into 'main'
fix(updateCredentialsController): stop overwriting kind 0 unnecessarily

Closes #269

See merge request soapbox-pub/ditto!598
2024-12-03 21:29:12 +00:00
P. Reis
2b6bf125e1 refactor(updateCredentialsController): accountFromPubkey if the user has no kind 0 2024-12-03 18:23:13 -03:00
P. Reis
dfff24d3b2 refactor(updateCredentialsController): return error if event is undefined 2024-12-03 15:22:37 -03:00
P. Reis
30d7f1a053 refactor(updateCredentialsController): stop overwriting kind 0 unnecessarily 2024-12-03 14:33:04 -03:00
P. Reis
b45fcdde69 Revert "fix(updateCredentialsController): stop overwriting kind 0 unnecessarily"
This reverts commit 342ba7d4b1.
2024-12-03 14:23:00 -03:00
Alex Gleason
cd95c38eec
'q' tag should omit marker per NIP-18 2024-11-30 13:14:16 -06:00
P. Reis
74ef00e9d8 refactor(getIdsBySearch): do not search if the search content is empty 2024-11-29 23:39:14 -03:00
Alex Gleason
f576e45c58
Upgrade gleasonator-policy in deno.lock 2024-11-29 18:55:38 -06:00
P. Reis
342ba7d4b1 fix(updateCredentialsController): stop overwriting kind 0 unnecessarily 2024-11-29 11:49:37 -03:00
Alex Gleason
45cb9757b4 Merge branch 'no-unauthenticated' into 'main'
Support Bluesky's !no-unauthenticated self-label

See merge request soapbox-pub/ditto!596
2024-11-26 06:52:12 +00:00
Alex Gleason
d86096dd91
Merge remote-tracking branch 'origin/main' into no-unauthenticated 2024-11-26 00:48:39 -06:00
Alex Gleason
beba62630a Merge branch 'fix-ci' into 'main'
Simplify CI

See merge request soapbox-pub/ditto!597
2024-11-26 06:12:59 +00:00
Alex Gleason
40215716db
Delete cursed pipeline test 2024-11-26 00:09:04 -06:00
Alex Gleason
840b7231cd
Simplify CI 2024-11-25 23:43:48 -06:00
Alex Gleason
4ed66b8fe5
accountLookupController: support !no-unauthenticated 2024-11-25 22:44:14 -06:00
Alex Gleason
1dc19ef422
Support Bluesky's !no-unauthenticated self-label 2024-11-25 22:36:32 -06:00
Alex Gleason
afb450e412
Bump gleasonator-policy in deno.lock 2024-11-25 19:44:20 -06:00
Alex Gleason
5ea5fd40a4
Bump gleasonator-policy in deno.lock 2024-11-25 19:41:10 -06:00
Alex Gleason
418dbd6d0c
Let a proxy tag not be a URL (to support atproto URIs) 2024-11-22 10:49:05 -06:00
Alex Gleason
da82462fa2
Remove other usages of : any 2024-11-22 10:28:26 -06:00
Alex Gleason
4eb7ea2461
Remove e: any from error handlers 2024-11-22 10:26:30 -06:00
Alex Gleason
ebaf2b9c59
Upgrade Deno to v2.1.1 2024-11-22 10:19:54 -06:00
Alex Gleason
f40a9d8a5a Merge branch 'ditto-retroactive-policies' into 'main'
add cleanup script (apply policy to events created before it applied)

Closes #232

See merge request soapbox-pub/ditto!590
2024-11-21 16:37:57 +00:00
Siddharth Singh
8607810117
delete events as they are streamed from db 2024-11-21 22:03:55 +05:30
Alex Gleason
1d803b3f32 Merge branch 'check-all' into 'main'
Type check scripts/

See merge request soapbox-pub/ditto!595
2024-11-21 16:28:22 +00:00
Alex Gleason
ceddcce4cf
Type check scripts/ 2024-11-21 10:25:15 -06:00
Alex Gleason
e38392b269 Merge branch 'deno-2.1' into 'main'
Upgrade to Deno 2.1.0

See merge request soapbox-pub/ditto!594
2024-11-21 16:20:15 +00:00
Alex Gleason
53a0c45663
Upgrade to Deno 2.1.0 2024-11-21 10:16:56 -06:00
Alex Gleason
6ee4e0877a Merge branch 'fields' into 'main'
Linkify profile field values

See merge request soapbox-pub/ditto!593
2024-11-20 17:09:45 +00:00
Alex Gleason
d2df2a5e22
Linkify profile field values 2024-11-20 11:06:36 -06:00
Alex Gleason
c25fd366a9 Merge branch 'fields' into 'main'
Instruct Soapbox to use up to 10 custom profile fields

See merge request soapbox-pub/ditto!592
2024-11-20 17:01:26 +00:00
Alex Gleason
81780bec72
Let field limits be configurable 2024-11-20 10:58:21 -06:00
Alex Gleason
39cb1ec0c9
renderAccount: only display up to 10 profile fields 2024-11-20 10:50:49 -06:00
Alex Gleason
7227202a86
Instruct Soapbox to use up to 10 custom profile fields 2024-11-20 10:49:19 -06:00
Alex Gleason
55d1297375 Merge branch 'fields' into 'main'
Add custom profile fields

See merge request soapbox-pub/ditto!591
2024-11-20 15:49:32 +00:00
Alex Gleason
098e1b7fff
Add a custom parseFormData helper to simulate Mastodon's (Rails) formdata parser 2024-11-20 09:46:09 -06:00
Alex Gleason
281f57d88e
Include fields in account.source 2024-11-20 09:45:52 -06:00
Alex Gleason
154056f8d6
Add custom profile fields 2024-11-20 08:58:12 -06:00
Siddharth Singh
a985d1add1
add cleanup script (apply policy to events created before it applied) 2024-11-17 22:17:26 +05:30
Alex Gleason
d2d29aef8f Merge branch 'fix-remove-strict' into 'main'
fix(updateInstanceSchema): remove zod strict()

See merge request soapbox-pub/ditto!589
2024-11-15 14:56:22 +00:00
P. Reis
8fccd7eb03 fix(updateInstanceSchema): remove zod strict() 2024-11-15 11:49:38 -03:00
Alex Gleason
ee4373bdab Merge branch 'fix-update-instance-admin-only' into 'main'
fix(updateInstanceController): use updateAdminEvent() function

See merge request soapbox-pub/ditto!588
2024-11-15 14:29:16 +00:00
P. Reis
d9cc8cc7c2 refactor(updateInstanceController): move async function out of callback 2024-11-15 11:20:10 -03:00
P. Reis
33b36ba0ed fix(updateInstanceController): use updateAdminEvent() function 2024-11-15 11:08:47 -03:00
Alex Gleason
7108b62193 Merge branch 'configdb' into 'main'
Add PleromaConfigDB module, include sentryDsn in CSP

See merge request soapbox-pub/ditto!579
2024-11-15 02:43:50 +00:00
Alex Gleason
aea31bce5d
csp: use the sentry origin instead of the URL itself 2024-11-14 20:28:14 -06:00
Alex Gleason
3d376ba8b3
csp: fix connect-src 2024-11-14 20:18:15 -06:00
Alex Gleason
02ada73f48
Include Soapbox sentryDsn in CSP 2024-11-14 20:12:27 -06:00
Alex Gleason
55f50ba93d
PleromaConfigDB: implement .getIn 2024-11-14 19:54:29 -06:00
Alex Gleason
3e27e902d5
Add PleromaConfigDB test 2024-11-14 17:49:30 -06:00
Alex Gleason
6492486a1a
Merge remote-tracking branch 'origin/main' into configdb 2024-11-14 17:46:30 -06:00
Alex Gleason
cc6d12c09b Merge branch 'fmt' into 'main'
deno fmt everything

See merge request soapbox-pub/ditto!587
2024-11-14 23:23:03 +00:00
Alex Gleason
03f0200114
deno fmt everything 2024-11-14 17:19:12 -06:00
Alex Gleason
5e523cbb1a
Merge remote-tracking branch 'origin/main' into configdb 2024-11-14 17:00:36 -06:00
Alex Gleason
1baab0f868 Merge branch 'make-sizes-optional' into 'main'
fix(screenshotsSchema): make sizes field optional

See merge request soapbox-pub/ditto!585
2024-11-14 16:17:04 +00:00
P. Reis
65ea84f429 Merge branch 'main' into make-sizes-optional 2024-11-13 19:15:00 -03:00
Alex Gleason
8a46d399fd Merge branch 'safe-fetch' into 'main'
Upgrade safe-fetch

See merge request soapbox-pub/ditto!586
2024-11-13 21:47:13 +00:00
Alex Gleason
515c70f038
Switch to httpbingo in tests so testing over https works 2024-11-13 15:34:41 -06:00
Alex Gleason
674781daf1
Upgrade safe-fetch 2024-11-13 15:23:42 -06:00
P. Reis
acee8784ee fix(screenshotsSchema): make sizes field optional 2024-11-13 17:19:11 -03:00
Alex Gleason
0bba4393ba
Remove unused ActivityPub schema 2024-11-11 19:54:59 -06:00
Alex Gleason
56a2e622e8
Remove deny-read from setup script 2024-11-10 10:37:05 -06:00
Alex Gleason
5c45517db4
deno task test: fix --deny-read flag 2024-11-07 17:02:08 -06:00
Alex Gleason
858692d2f3 Merge branch 'fix-updateInstanceController-schema' into 'main'
Update updateInstanceController schema

See merge request soapbox-pub/ditto!584
2024-11-07 21:34:17 +00:00
P. Reis
3a656e6f61 fix: remove unused imports 2024-11-07 18:31:28 -03:00
P. Reis
715908082f fix(updateInstanceController): stop using screenshot_ids and thumbnail_id 2024-11-07 18:18:33 -03:00
Alex Gleason
3dafe2b6d1
playbook: upgrade Deno 2024-11-07 13:40:37 -06:00
Alex Gleason
66894c3a18 Merge branch 'deny-read-env' into 'main'
Deny reading .env

See merge request soapbox-pub/ditto!583
2024-11-07 19:36:44 +00:00
Alex Gleason
459adadd4c
Deny reading .env 2024-11-07 13:32:53 -06:00
Alex Gleason
6fae72b4cf
upload: append file size if it hasn't been 2024-11-07 13:10:15 -06:00
P. Reis
115641b3c2 fix: add short_description to instanceV2Controller 2024-11-07 15:22:28 -03:00
Alex Gleason
95c7c4f87c Merge branch 'deno-2.0.5' into 'main'
Upgrade Deno to v2.0.5

See merge request soapbox-pub/ditto!582
2024-11-07 17:35:44 +00:00
Alex Gleason
e1dc3d79a4
Upgrade Deno to v2.0.5 2024-11-07 11:32:34 -06:00
Alex Gleason
fe222f37e0 Merge branch 'ipfs-image-metadata' into 'main'
Add additional image metadata for images

Closes #248

See merge request soapbox-pub/ditto!570
2024-11-07 17:21:53 +00:00
Alex Gleason
f987effc15
Make media analyze optional (disabled by default) 2024-11-07 11:18:39 -06:00
Alex Gleason
721fe52142
Reorganize sharp/blurhash into upload.ts 2024-11-07 11:09:20 -06:00
Alex Gleason
a294724946
Merge remote-tracking branch 'origin/main' into ipfs-image-metadata 2024-11-07 10:13:30 -06:00
Siddharth Singh
e96a9e4f35
replace toByteArray with Response(stream).bytes() 2024-11-06 12:12:27 +05:30
Alex Gleason
840cacd561 Merge branch 'add-short-description-field' into 'main'
fix(updateInstanceController): allow for setting the tagline

See merge request soapbox-pub/ditto!581
2024-11-05 17:39:55 +00:00
P. Reis
9907d7ffd8 fix(updateInstanceController): allow for setting the tagline 2024-11-05 14:36:48 -03:00
Alex Gleason
7f02657306 Merge branch 'feat-set-kind-0-api' into 'main'
Create updateInstanceController endpoint (allow for setting the kind 0, screenshots go into kind 0 content)

Closes #259 and #257

See merge request soapbox-pub/ditto!577
2024-11-05 17:02:08 +00:00
P. Reis
af0211d65b fix(updateInstanceController): remove 'event' field from meta 2024-11-05 09:46:33 -03:00
P. Reis
ea24050a27 refactor: change thumbnailSchema to schemas/mastodon.ts 2024-11-05 09:02:27 -03:00
Alex Gleason
8b3f8809ee Merge branch 'wellknown' into 'main'
Let users host arbitrary .well-known paths

See merge request soapbox-pub/ditto!580
2024-11-04 23:43:25 +00:00
Alex Gleason
e3aed99605
Let users host arbitrary .well-known paths 2024-11-04 17:23:30 -06:00
Alex Gleason
1a50578b39
Add PleromaConfigDB module 2024-11-04 10:12:58 -06:00
P. Reis
f92c382da9 refactor: remove unused imports 2024-11-04 11:16:36 -03:00
P. Reis
bac2c51bc1 refactor: use screenshot_ids and thumbnail_id in updateInstanceController 2024-11-04 11:12:16 -03:00
P. Reis
cd7e6bbd43 feat: create thumbnailSchema 2024-11-04 11:10:27 -03:00
P. Reis
34d604dded refactor: sizesSchema 2024-11-03 20:27:52 -03:00
P. Reis
c411a871ef Merge branch 'main' into feat-set-kind-0-api 2024-11-01 23:19:53 -03:00
P. Reis
f0be2a1c02 fix: set thumbnail in 2024-11-01 23:19:17 -03:00
P. Reis
339b13c084 feat: create updateInstanceController
for now only update: title, description, screenshots (user must provide the image URL) and thumbnail (user must provide the image URL)
screenshots array is stored in the content of the kind 0 of the
2024-11-01 23:14:59 -03:00
P. Reis
c6ff4a9d25 feat: add sizesSchema 2024-11-01 23:07:51 -03:00
P. Reis
03d93ff810 fix: 'Context' resolves to a type-only declaration and must be imported using a type-only import when 'verbatimModuleSyntax' is enabled. 2024-11-01 18:14:51 -03:00
Alex Gleason
d46af51604 Merge branch 'ephemeral' into 'main'
pipeline: improve error handling, include special treatment for ephemeral and NIP-46 events

See merge request soapbox-pub/ditto!576
2024-10-31 22:35:58 +00:00
Alex Gleason
e766f6c757
pipeline: improve error handling, include special treatment for ephemeral and NIP-46 events 2024-10-31 16:06:58 -05:00
Alex Gleason
47eca9e2f7 Merge branch 'fix-render-link-about' into 'main'
fix: render HTML link in bio

Closes #9

See merge request soapbox-pub/ditto!575
2024-10-31 17:06:43 +00:00
P. Reis
a883aea585 refactor: remove stripimeta in 'about' of renderAccount 2024-10-31 14:03:36 -03:00
P. Reis
e3fec6b938 fix: render HTML link in bio 2024-10-31 11:48:43 -03:00
Alex Gleason
40c24d927f Merge branch 'fix-bio-number' into 'main'
fix: users can set their bio to a number

Closes #184

See merge request soapbox-pub/ditto!574
2024-10-30 19:28:25 +00:00
P. Reis
94431fadcd fix: users can set their display_name to a number 2024-10-30 13:59:32 -03:00
P. Reis
0a7c0c60a9 fix: users can set their bio to a number 2024-10-30 13:48:35 -03:00
Siddharth Singh
38288aadb3
move tag logic to upload.ts 2024-10-30 11:06:48 +05:30
Siddharth Singh
e95441f5b9
revert changes to IPFSUploader and S3Uploader 2024-10-30 11:04:19 +05:30
Alex Gleason
96a11d42c9 Merge branch 'push-404' into 'main'
Fix 404 error in Web Push API

See merge request soapbox-pub/ditto!573
2024-10-29 18:08:51 +00:00
Alex Gleason
dc73749277
Fix 404 error in Web Push API 2024-10-29 13:05:50 -05:00
Alex Gleason
324ee58bd0 Merge branch 'fix-follow-people' into 'main'
fix: follow people

Closes #258

See merge request soapbox-pub/ditto!572
2024-10-29 14:13:43 +00:00
P. Reis
6fd0c273cb fix: follow people
create a new migration that replaces the function to NOTIFY only the event id
2024-10-29 11:07:51 -03:00
Alex Gleason
9260c2ba90 Merge branch 'sticky-streaming' into 'main'
refactor(streaming): use better Sticky

See merge request soapbox-pub/ditto!571
2024-10-29 00:39:21 +00:00
P. Reis
fef787faad refactor(streaming): use better Sticky 2024-10-28 20:41:07 -03:00
Alex Gleason
8ff4a0bdbd Merge branch 'fix-statuses-posts-pagination' into 'main'
Fix pagination when searching for posts, enhance search a little bit

Closes #255

See merge request soapbox-pub/ditto!567
2024-10-27 20:48:47 +00:00
P. Reis
3c3f90eddb refactor: kysely.selectNoFrom 2024-10-27 17:44:35 -03:00
P. Reis
f259ab8d88 refactor: rename queryWithoutPhraseto_tsquery to fallbackQuery 2024-10-27 15:50:15 -03:00
P. Reis
d06e0311c9 refactor: if statement lexemes 2024-10-27 15:48:04 -03:00
P. Reis
e8c66c77fc refactor: don't parse twice 2024-10-27 15:41:21 -03:00
P. Reis
a690a2ff6f Merge branch 'main' into fix-statuses-posts-pagination 2024-10-27 15:39:39 -03:00
P. Reis
553b17c646 refactor: tsdoc format 2024-10-27 15:38:35 -03:00
Alex Gleason
d52e717fb2
EventsDB: fix domain query with authors 2024-10-27 10:03:22 -05:00
Siddharth Singh
57725fa9ac
neatness 2024-10-27 10:21:53 +05:30
Siddharth Singh
713260e110
split off nip94 metadata stuff into its own file, port changes to s3uploader 2024-10-27 10:16:00 +05:30
Siddharth Singh
ff8374103e
remove unused dep 2024-10-27 10:00:47 +05:30
Siddharth Singh
f5f31ce98f
fix image uploads, use sharp to get image metadata instead of image-information 2024-10-27 09:13:48 +05:30
Siddharth Singh
de4b5f55d3
update lockfile 2024-10-27 09:13:48 +05:30
Siddharth Singh
b0a2422437
add more metadata to IPFSUploader 2024-10-27 09:13:48 +05:30
Alex Gleason
6171a321e2 Merge branch 'tribes-dockerfile-stuff' into 'main'
add allow-import flag to dockerfile

See merge request soapbox-pub/ditto!569
2024-10-27 02:29:45 +00:00
Alex Gleason
9b473406cf Merge branch 'bunker-pubkey' into 'main'
Let bunker_pubkey be different from user pubkey

See merge request soapbox-pub/ditto!568
2024-10-26 23:46:15 +00:00
Alex Gleason
42f5e316a8
Let bunker_pubkey be different from user pubkey 2024-10-26 18:37:26 -05:00
P. Reis
d27ab3ce49 fix: pagination in searching statuses 2024-10-26 18:58:02 -03:00
P. Reis
8b050e7df1 question: isn't Kysely immutable?
cc https://www.kysely.dev/docs/getting-started#querying
2024-10-26 18:53:19 -03:00
P. Reis
bbd692c58f fix(extractIdentifier): only return value if it has a domain
before this commit, if the value was  it would be true
2024-10-26 18:50:42 -03:00
Alex Gleason
d28db38ba9 Merge branch 'deno-2.0.3' into 'main'
Upgrade deno to v2.0.3

See merge request soapbox-pub/ditto!566
2024-10-26 21:15:20 +00:00
Alex Gleason
eb5db9a30b
Upgrade deno to v2.0.3 2024-10-26 15:57:06 -05:00
Alex Gleason
2b4efd6a03 Merge branch 'fix-search-profile-pagination' into 'main'
fix: search profiles with offset pagination

See merge request soapbox-pub/ditto!564
2024-10-24 00:09:17 +00:00
P. Reis
89e475ca4a fix: offset of zero 0 in accountSearchController 2024-10-23 20:42:10 -03:00
P. Reis
994dff8e79 fix: search profiles with offset pagination 2024-10-23 20:37:31 -03:00
Alex Gleason
28b874edc9 Merge branch 'fix-zap-pubkey-duplication' into 'main'
fix: duplicate pubkey of 'self' if zap tag

See merge request soapbox-pub/ditto!561
2024-10-20 02:21:00 +00:00
Alex Gleason
9ad9adcff5 Merge branch 'notify' into 'main'
Perform listen/notify of Nostr events to the pipeline

Closes #219

See merge request soapbox-pub/ditto!562
2024-10-20 02:18:22 +00:00
P. Reis
7d27a6e890 refactor: rewrite if statement 2024-10-19 23:16:04 -03:00
Alex Gleason
013917d612
Expose a generic listen method on the database adapters 2024-10-19 21:01:42 -05:00
Alex Gleason
4df61c0c59
pipeline: remove "event already in database" check 2024-10-19 20:55:09 -05:00
P. Reis
0abd567824 fix: duplicate pubkey of 'self' if zap tag 2024-10-19 22:31:41 -03:00
Alex Gleason
8155fae89a
Perform listen/notify of Nostr events to the pipeline 2024-10-19 20:27:46 -05:00
Alex Gleason
92a1d88923
Use Ditto planet as default instance thumbnail 2024-10-19 19:19:13 -05:00
Alex Gleason
67b17778d3 Merge branch 'all-trends-pagination' into 'main'
feat: pagination with Link headers in trendingStatusesController

Closes #236

See merge request soapbox-pub/ditto!560
2024-10-19 16:38:16 +00:00
P. Reis
e5d0634864 feat: pagination with Link headers in trendingStatusesController 2024-10-18 19:23:02 -03:00
Alex Gleason
10e1967ad3 Merge branch 'fix-zap-sender-missing-kind-0' into 'main'
Fix zap sender missing kind 0

Closes #237 and #254

See merge request soapbox-pub/ditto!558
2024-10-18 18:55:06 +00:00
Alex Gleason
68c1b31940 Merge branch 'dotenv' into 'main'
Add .env.test, use --env-file flag, remove TEST_DATABASE_URL, remove @std/dotenv

See merge request soapbox-pub/ditto!559
2024-10-18 18:39:55 +00:00
Alex Gleason
de2c0effbf
Remove import '@/config.ts' from trends script 2024-10-18 13:29:34 -05:00
Alex Gleason
c390481939
Remove TEST_DATABASE_URL 2024-10-18 13:25:39 -05:00
Alex Gleason
f6046c015b
Remove @std/dotenv 2024-10-18 13:22:34 -05:00
Alex Gleason
8944594c71
Pass --env-file into deno tasks, use a separate .env.test for tests 2024-10-18 13:20:30 -05:00
Alex Gleason
ef7c9e14db Merge branch 'ci-truncate' into 'main'
Speed up migrations in tests

See merge request soapbox-pub/ditto!557
2024-10-18 18:13:16 +00:00
P. Reis
f581dcbcfb fix(hydrate): make gatherAuthors() function async 2024-10-18 14:35:30 -03:00
P. Reis
a1bf808efd fix: remove 'HEAD' from previous conflict 2024-10-18 14:30:15 -03:00
P. Reis
ceaf6534ae Merge branch 'main' into fix-zap-sender-missing-kind-0 2024-10-18 14:27:42 -03:00
Alex Gleason
08cc4f1db9
Speed up migrations in tests 2024-10-18 12:24:49 -05:00
P. Reis
ead96af16f fix: get all zap related authors (receivers, senders) inside gatherAuthors() function 2024-10-18 14:23:38 -03:00
Alex Gleason
b876cf368a Merge branch 'fix-zap-post' into 'main'
fix(zapController): remove not needed arguments

See merge request soapbox-pub/ditto!556
2024-10-18 17:13:08 +00:00
P. Reis
0516fb6ce8 fix(zapController): remove not needed arguments 2024-10-18 14:08:47 -03:00
Alex Gleason
5b080c7bc0 Merge branch 'hydrate-null-author' into 'main'
Hydrate null authors

Closes #168

See merge request soapbox-pub/ditto!552
2024-10-18 14:55:34 +00:00
Alex Gleason
035c57ac89 Merge branch 'deno-2.0.2' into 'main'
Upgrade Deno to v2.0.2

See merge request soapbox-pub/ditto!555
2024-10-18 13:38:46 +00:00
Alex Gleason
52df3b240e
Upgrade Deno to v2.0.2 2024-10-17 22:30:17 -05:00
Alex Gleason
4be6fe004d Merge branch 'manifest-icons' into 'main'
webmanifest: add app icons

See merge request soapbox-pub/ditto!554
2024-10-17 23:22:03 +00:00
Alex Gleason
5d484e4bf6
webmanifest: add app icons 2024-10-17 18:15:11 -05:00
Alex Gleason
6ea71865f1
hydrate: build fallback authors during gatherAuthors step 2024-10-17 15:26:23 -05:00
Alex Gleason
28e8dfb4ac Merge branch 'push-zap-amount' into 'main'
Fix zap amount in web push notification

See merge request soapbox-pub/ditto!553
2024-10-17 20:21:21 +00:00
Alex Gleason
4293092756
Fix zap amount in web push notification
Ref: https://gleasonator.dev/@idsera@ditto.pub/posts/eeddba51bb15e06654afd1952e62bd91d2248d9517ba499024b09887081dd919
2024-10-17 15:16:14 -05:00
Alex Gleason
33e5b20159
Hydrate null authors 2024-10-17 15:04:57 -05:00
Alex Gleason
96416747c2 Merge branch 'revoke' into 'main'
Implement OAuth revoke endpoint

See merge request soapbox-pub/ditto!551
2024-10-17 19:24:53 +00:00
Alex Gleason
b4b7381b49
Implement OAuth revoke endpoint 2024-10-17 14:20:42 -05:00
Alex Gleason
66583e7f60 Merge branch 'ci-rm-postgres' into 'main'
Get rid of Postgres job in CI

See merge request soapbox-pub/ditto!550
2024-10-17 03:50:12 +00:00
Alex Gleason
5e415f897f
Get rid of Postgres job in CI 2024-10-16 22:43:38 -05:00
Alex Gleason
2764cbf97a Merge branch 'deno-2.0.1' into 'main'
Upgrade to Deno v2.0.1

See merge request soapbox-pub/ditto!549
2024-10-17 03:30:26 +00:00
Alex Gleason
6e00412cc3
Upgrade to Deno v2.0.1 2024-10-16 20:27:46 -05:00
Alex Gleason
d1635712cf
Use nprofile and nevent links for external URLs in Account and Status 2024-10-16 10:13:37 -05:00
Alex Gleason
30d8cc4108
Test that DeepL translation doesn't alter Nostr URIs 2024-10-16 09:58:49 -05:00
Alex Gleason
bfe2c620e6
renderWebPushNotification: fix account without display_name 2024-10-15 17:16:53 -05:00
Alex Gleason
7fbda4a56b
Move push notification rendering to its own view 2024-10-15 17:13:39 -05:00
Alex Gleason
8bf0a443db
pipeline: Promise.all -> Promise.allSettled 2024-10-15 16:27:48 -05:00
Alex Gleason
45cf74c168
Encode VAPID public key with base64url 2024-10-15 15:51:52 -05:00
Alex Gleason
5b6cacc2ed Merge branch 'push' into 'main'
Add Web Push API

See merge request soapbox-pub/ditto!524
2024-10-15 15:41:21 +00:00
Alex Gleason
d9d280e6c1
Merge remote-tracking branch 'origin/main' into push 2024-10-14 19:59:37 -05:00
Alex Gleason
7ee1ca51d6
Delete not working controller test 2024-10-14 18:20:41 -05:00
Alex Gleason
95d970d8d0
webpush: add metrics and pipeline error handling 2024-10-14 18:06:22 -05:00
Alex Gleason
462f4ad786
Add placeholder data to push notification 2024-10-14 17:44:49 -05:00
Alex Gleason
4c5d98f402
webpush: don't notify author about own events 2024-10-14 17:31:05 -05:00
Alex Gleason
a7d8d86fa7
Add GET /api/v1/notifications/:id endpoint 2024-10-14 17:27:30 -05:00
Alex Gleason
30a5d9a20f
webpush: fix query error in pipeline 2024-10-14 16:24:13 -05:00
Alex Gleason
94d8d43d78
Add unique index on push_subscriptions token_hash 2024-10-14 16:02:07 -05:00
Alex Gleason
4019099c57
Add endpoint to GET a push subscription 2024-10-14 15:48:55 -05:00
Alex Gleason
b3928bac45
webpush: replace old subscriptions in transaction 2024-10-14 14:31:33 -05:00
Alex Gleason
94cf3b2931
Add push controller test 2024-10-13 23:29:06 -05:00
Alex Gleason
260340c58e
Fix EventsDB test 2024-10-13 16:41:20 -05:00
Alex Gleason
feec343d5a
EventsDB: fix plaintext search queries 2024-10-13 16:22:03 -05:00
Siddharth Singh
61ee6e5e8d
add allow-import flag to dockerfile 2024-10-13 23:47:29 +05:30
Alex Gleason
b6925a5491
webpush: enforce endpoint as a URL 2024-10-12 22:58:29 -05:00
Alex Gleason
3fa12e3ba5
Merge remote-tracking branch 'origin/main' into push 2024-10-11 18:06:37 -05:00
Alex Gleason
a7bca0bdff
Remove DittoWallet module 2024-10-11 18:06:17 -05:00
Alex Gleason
b4e63afb8c
Merge remote-tracking branch 'origin/main' into push 2024-10-11 18:03:20 -05:00
Alex Gleason
b2397bccdd
Upgrade @gleasonator/policy in deno.lock 2024-10-11 17:44:29 -05:00
Alex Gleason
7dff4e88d4 Merge branch 'captcha-n' into 'main'
Switch captcha_solved from a label event to an n-tag on a user event

See merge request soapbox-pub/ditto!547
2024-10-11 22:43:39 +00:00
Alex Gleason
d4f3c673a2
deno lint 2024-10-11 17:35:45 -05:00
Alex Gleason
81a15ac82d Merge branch 'improve-lande-use' into 'main'
Improve setLanguage() function for better language detection

See merge request soapbox-pub/ditto!543
2024-10-11 21:52:11 +00:00
Alex Gleason
a484634d36
Switch captcha_solved from a label event to an n-tag on a user event 2024-10-11 16:50:52 -05:00
P. Reis
9c7e35a6b4 refactor: code preferences, formatting 2024-10-11 18:47:38 -03:00
Alex Gleason
432229c0f0 Merge branch 'update-credentials-fix' into 'main'
Make verify_credentials and update_credentials return a consistent CredentialAccount object

See merge request soapbox-pub/ditto!546
2024-10-11 21:31:22 +00:00
Alex Gleason
c5ddd2ebb7
Make verify_credentials and update_credentials return a consistent CredentialAccount object 2024-10-11 16:25:29 -05:00
P. Reis
36d09af467 feat: make lande great again
create detectLanguage() function that removes emojis, links and other weird invisible characters
2024-10-11 14:28:01 -03:00
Alex Gleason
fab0c8a409 Merge branch 'upgrade-dockerfile-deno-version' into 'main'
upgrade deno version in dockerfile

See merge request soapbox-pub/ditto!544
2024-10-11 16:29:23 +00:00
Siddharth Singh
380ac42033
upgrade deno version in dockerfile 2024-10-11 21:50:40 +05:30
Alex Gleason
6fb3bfafc0
Mark registrations enabled in v2 instance 2024-10-11 02:52:41 -05:00
P. Reis
1cb13b141a feat: improve setLanguage() function, remove links and emojis from event.content before using lande 2024-10-10 22:46:37 -03:00
Alex Gleason
522a283af1 Merge branch 'translator-env' into 'main'
Translation refactors

See merge request soapbox-pub/ditto!542
2024-10-10 19:22:12 +00:00
Alex Gleason
df3b8863df
LibreTranslateTranslator: move headers to plain object, add url variable 2024-10-10 14:16:29 -05:00
Alex Gleason
655e94ef91
DittoTranslator: move provider to top of interface 2024-10-10 14:14:29 -05:00
Alex Gleason
12d643e150
Add translation cache metrics, let the cache be configurable 2024-10-10 14:12:20 -05:00
Alex Gleason
d639d9a14d
Reorganize translation interfaces/files 2024-10-10 14:06:04 -05:00
Alex Gleason
874da1baad
Delete unused cacheMiddleware and ExpiringCache module 2024-10-10 14:01:18 -05:00
Alex Gleason
9469fff6ac
Rename translation variables from _ENDPOINT to _BASE_URL 2024-10-10 13:48:50 -05:00
Alex Gleason
b6f9fe5770
grafana: ditto_db_query_duration_ms -> ditto_db_query_duration_seconds 2024-10-10 13:26:05 -05:00
Alex Gleason
4597d1018e Merge branch 'http-metrics' into 'main'
Record HTTP response time metrics

See merge request soapbox-pub/ditto!541
2024-10-10 18:25:17 +00:00
Alex Gleason
6107ce88e2
metrics: ditto_db_query_duration_ms -> ditto_db_query_duration_seconds 2024-10-10 13:20:48 -05:00
Alex Gleason
81c28825a8
Record HTTP response time metrics 2024-10-10 13:20:03 -05:00
Alex Gleason
df8004e261
Decrease rate limit of translations 2024-10-09 21:04:05 -05:00
Alex Gleason
33d2eb6ca3
Remove Provider type (it's just a string) 2024-10-09 21:02:55 -05:00
Alex Gleason
c048cda2e5
Upgrade @gleasonator/policy in deno.lock, increase policy db timeout
Fixes https://gitlab.com/soapbox-pub/ditto/-/issues/244
2024-10-09 20:22:12 -05:00
Alex Gleason
d4767f56c6
Enable translations dynamically depending on whether a TRANSLATION_PROVIDER is set 2024-10-09 20:17:04 -05:00
Alex Gleason
878535c428 Merge branch 'worker-names' into 'main'
Add names to web workers

See merge request soapbox-pub/ditto!540
2024-10-09 22:59:15 +00:00
Alex Gleason
4d146dcc98
Add names to web workers 2024-10-09 17:58:11 -05:00
Alex Gleason
0819049cb8 Merge branch 'handle-translate-error-not-supported' into 'main'
feat: return translation not supported error to the frontend

See merge request soapbox-pub/ditto!539
2024-10-09 22:24:09 +00:00
P. Reis
b86bd81ed2 refactor: cast correct error type 2024-10-09 19:19:54 -03:00
P. Reis
87e0f594df refactor: throw new Error to have benefit of stack trace 2024-10-09 19:17:03 -03:00
P. Reis
54fa38795a feat: return translation not supported error to the frontend 2024-10-09 18:52:23 -03:00
Alex Gleason
91b82c36a8 Merge branch 'translate-status' into 'main'
Feat: Support Machine Translations

Closes #201

See merge request soapbox-pub/ditto!537
2024-10-09 18:59:04 +00:00
P. Reis
cad0da2732 feat: rateLimit translate endpoint 2024-10-09 15:24:01 -03:00
P. Reis
57bbbb289b fix: types must have the type prefix
apparently happens in Deno 2.0?
2024-10-09 15:22:09 -03:00
P. Reis
22fa3f944c chore: update nostrify:db 2024-10-09 15:18:20 -03:00
P. Reis
728d7b33fb Merge branch 'main' into translate-status
Conflicts:
	deno.lock
        I have let the changes of main to prevail, I will update nostrify:db manually
2024-10-09 15:14:22 -03:00
P. Reis
4f8c8fd1de refactor: simply DittoTranslator interface and classes that implement it 2024-10-09 15:03:11 -03:00
P. Reis
c1c25d7c08 feat: create localeSchema 2024-10-09 14:57:28 -03:00
Alex Gleason
376fd8a956 Merge branch 'deno-2.0.0' into 'main'
Upgrade to Deno v2.0

See merge request soapbox-pub/ditto!538
2024-10-09 09:38:33 +00:00
Alex Gleason
df92483617
Add --allow-import to check task 2024-10-09 04:25:49 -05:00
Alex Gleason
bf2e20f2ce
Upgrade to Deno v2.0 2024-10-09 04:17:55 -05:00
Alex Gleason
d6b65245ea
Fix dompurify in deno.lock 2024-10-09 04:01:08 -05:00
Alex Gleason
90e0de2cac
Upgrade dompurify 2024-10-08 23:23:52 -05:00
Alex Gleason
455b2671f7
Merge remote-tracking branch 'origin/main' into push 2024-10-08 20:11:30 -05:00
Alex Gleason
11193fa689
Upgrade @gleasonator/policy in deno.lock 2024-10-08 20:11:12 -05:00
Alex Gleason
8278dbe152
Remove bip32 2024-10-08 20:02:10 -05:00
Alex Gleason
198ec973b6
Load VAPID keys from configuration 2024-10-08 19:57:46 -05:00
Alex Gleason
8f437839d0
Delete DittoWallet 2024-10-08 18:37:59 -05:00
Alex Gleason
8823c0987d
Actually push ?? 2024-10-08 18:37:23 -05:00
P. Reis
49d815826c refactor(languageSchema): enforce return type 2024-10-08 17:07:05 -03:00
P. Reis
fc5e9b2990 Revert "refactor: move getConfigs() function and frontendConfig logic to 'src/utils/frontendConfig.ts'"
This reverts commit ab85360d2f.

The discussion started publicly in Gitlab: https://gitlab.com/soapbox-pub/ditto/-/merge_requests/537#note_2148430111
Then it kept going in Element, basically the purpose of the commit is
correct, but the way Patrick did it is not good.
2024-10-08 16:58:42 -03:00
P. Reis
20caaa9ebd refactor: LibreTranslate and DeepL with separate environment variables for their configuration 2024-10-08 16:53:30 -03:00
Alex Gleason
1ed6cac1c4
Add a crypto module to convert ECDSA private CryptoKey into a public key 2024-10-08 13:56:46 -05:00
Alex Gleason
8abac7ffa7
InstanceV2: remove supported_mime_types property 2024-10-08 12:52:14 -05:00
P. Reis
dbd590228d fix: typo 2024-10-08 14:39:59 -03:00
Alex Gleason
6430dd11ad
Merge remote-tracking branch 'origin/main' into push 2024-10-08 12:37:11 -05:00
P. Reis
f76ee000b0 refactor: use 'lang' instead of 'target_language' 2024-10-08 14:35:51 -03:00
Alex Gleason
e6495c3687
Also add nostr to InstanceV2 2024-10-08 12:35:03 -05:00
Alex Gleason
248324f642
Add pleroma to InstanceV2 2024-10-08 12:32:00 -05:00
P. Reis
a3bc5ec5c3 refactor: remove translation enabled in instanceV1Controller 2024-10-08 14:27:00 -03:00
P. Reis
ba23931727 refactor: remove unused imports 2024-10-08 14:25:25 -03:00
P. Reis
d4a8ec21fe fix: add 'pure' option in EventsDB
if pure is true, EventsDB will return a Nostr event, otherwise it will return a Ditto event
2024-10-08 14:17:27 -03:00
P. Reis
df27959d35 fix(relay.ts): purify event 2024-10-08 14:15:48 -03:00
P. Reis
17be4ab48f fix(instanceV1Controller): add translation field 2024-10-08 11:11:29 -03:00
P. Reis
3f00f255a5 fix: type assertions in EventsDB 2024-10-08 11:01:34 -03:00
P. Reis
6c93153117 refactor: get language from event itself 2024-10-07 17:55:50 -03:00
P. Reis
acbdae29ae fix(EventsDB): type is correct, ignore type complaint 2024-10-07 17:54:41 -03:00
P. Reis
bfab84d937 refactor: make provider lowercase because supporting case insensitive is allegedly protocol bloat 2024-10-07 17:54:03 -03:00
P. Reis
4712cb1d80 fix: fix language property in the Mastodon API 2024-10-07 16:08:23 -03:00
P. Reis
bbbce958d9 chore: update nostrify:db 2024-10-07 16:04:59 -03:00
P. Reis
01a16473ab Merge branch 'main' into translate-status 2024-10-07 15:02:47 -03:00
P. Reis
b369b2171d feat: create translateController - /api/v1/statuses/:id/translate 2024-10-07 15:02:04 -03:00
P. Reis
8e58b1a7d4 feat: create translatorMiddleware 2024-10-07 15:00:46 -03:00
P. Reis
a2d8478e1a test(LibreTranslateTranslator): create multiple tests 2024-10-07 14:59:05 -03:00
P. Reis
c23ddb7d84 feat: create LibreTranslateTranslator class that implements DittoTranslator 2024-10-07 14:58:33 -03:00
P. Reis
321d26b470 test(DeepLTranslator): create multiple tests 2024-10-07 14:55:12 -03:00
P. Reis
27f435a93c feat: create DeepLTranslator class that implements DittoTranslator 2024-10-07 14:54:10 -03:00
P. Reis
ea4d0f002a feat: create dittoTranslations LRUCache, create DittoTranslator interface, create MastodonTranslation type, create DittoTranslation type, create Provider type and some other minor ones 2024-10-07 14:42:10 -03:00
P. Reis
f434f87584 feat(instanceV2Controller): enable translation 2024-10-07 14:39:42 -03:00
P. Reis
c6626313bc feat: get TRANSLATION_PROVIDER, TRANSLATION_PROVIDER_ENDPOINT & TRANSLATION_PROVIDER_API_KEY enviornment variables 2024-10-07 14:38:55 -03:00
P. Reis
de8eba4079 feat: create getLanguage() function, used for testing purposes 2024-10-07 14:37:53 -03:00
P. Reis
0d126ad3b7 feat(languageSchema): split value to extract only language and not country code
pt-BR becomes pt
en-US becomes en
2024-10-07 14:36:26 -03:00
Alex Gleason
ff2553eb0f
Return a PushSubscription response 2024-10-06 16:07:32 -05:00
Alex Gleason
757b6c7e1c
Merge remote-tracking branch 'origin/main' into push 2024-10-06 15:51:50 -05:00
Alex Gleason
406cc6506b Merge branch 'captcha' into 'main'
Puzzle Captcha API

See merge request soapbox-pub/ditto!536
2024-10-05 20:59:37 +00:00
Alex Gleason
3aaf5030ca
captcha: add a small amount of noise 2024-10-05 15:24:44 -05:00
P. Reis
f3b7f91a07 feat: languageSchema converts value to lowercase and returns type LanguageCode 2024-10-04 23:37:01 -03:00
Alex Gleason
1cd7c99bda
Add account.source.ditto.captch_solved field 2024-10-04 19:26:47 -05:00
Alex Gleason
3b5b4cbd6b
Expose the Ditto pubkey to the policy worker 2024-10-04 19:21:56 -05:00
Alex Gleason
a2e8de6c36
Rate-limit the captcha endpoints 2024-10-04 16:48:24 -05:00
Alex Gleason
5ed683b146
Add puzzle source files 2024-10-04 16:43:33 -05:00
Alex Gleason
18f1a94520
captcha: show a random image, preload backgrounds into memory 2024-10-04 16:42:02 -05:00
Alex Gleason
c81005a050
captcha: refactor canvas size globals 2024-10-04 15:56:32 -05:00
Alex Gleason
6d09f69e26
Move captcha graphics 2024-10-04 15:48:34 -05:00
Alex Gleason
71873997e5
captcha: refactor canvas calls 2024-10-04 15:42:01 -05:00
Alex Gleason
cdf727e5c7
captcha: use an already transparent png with stroke to make the hole 2024-10-04 15:10:42 -05:00
Alex Gleason
030bfa94d6
captcha: rename puzzle to bg, and piece to puzzle 2024-10-04 14:22:17 -05:00
Alex Gleason
68c0d437ee
captcha: resize pieces, require nip98 auth 2024-10-04 13:34:12 -05:00
Alex Gleason
952d5e4370
Publish a label when the user solves a captcha 2024-10-04 12:53:37 -05:00
Alex Gleason
467a49bd40
Add captcha verify controller 2024-10-04 12:43:29 -05:00
Alex Gleason
e57dd8911c
captcha: don't do the encryption thing, just use a ttl cache 2024-10-04 12:07:12 -05:00
Alex Gleason
03c9340eb2
Mask the puzzle piece 2024-10-03 20:15:16 -05:00
Alex Gleason
707674db7c
Add captcha token comment 2024-10-03 19:38:03 -05:00
Alex Gleason
0bf41bc913
Use Pleroma's captcha endpoint (we basically match their return type) 2024-10-03 19:37:14 -05:00
Alex Gleason
8d1b1b8abc
Add encrypted captcha answer, move AES utils 2024-10-03 19:36:44 -05:00
Alex Gleason
f83ad0dbce
Add preliminary captcha controller 2024-10-03 19:23:22 -05:00
Alex Gleason
045508c4ba Merge branch 'more-dockerfile-fixes' into 'main'
remove expose directive in Dockerfile

See merge request soapbox-pub/ditto!534
2024-10-04 00:22:07 +00:00
Alex Gleason
d0666ff818 Merge branch 'fix-db-export' into 'main'
fix filter generation in db:export

See merge request soapbox-pub/ditto!533
2024-10-04 00:20:00 +00:00
Siddharth Singh
92aebbc847
remove stupid expose directive 2024-10-04 05:46:49 +05:30
Siddharth Singh
04f155580c
fix filter generation in db:export 2024-10-04 05:33:24 +05:30
Alex Gleason
205b9a77fe Merge branch 'wallet' into 'main'
Add an HD wallet

See merge request soapbox-pub/ditto!532
2024-10-03 22:56:58 +00:00
P. Reis
2ca421bef2 Merge branch 'main' into translate-status 2024-10-03 19:56:13 -03:00
Alex Gleason
e153020597
Add an HD wallet 2024-10-03 17:51:47 -05:00
Alex Gleason
cec16487ba Merge branch 'trends-any-language' into 'main'
Trends in any language

Closes #222

See merge request soapbox-pub/ditto!523
2024-10-03 22:44:37 +00:00
P. Reis
67b0684a81 refactor(trends.ts): move logic one level up, rename 'languagesIds' to 'values', remove WITH SQL statement 2024-10-03 19:40:29 -03:00
P. Reis
a5def9fa6c refactor: just import config.ts directly instead of loading dotenv in trends.ts script 2024-10-03 18:16:23 -03:00
Alex Gleason
e064531ca2 Merge branch 'run-dockerfile-as-root' into 'main'
run Dockerfile as root

See merge request soapbox-pub/ditto!531
2024-10-03 21:03:45 +00:00
Siddharth Singh
018600058a
run Dockerfile as root 2024-10-04 02:29:54 +05:30
Alex Gleason
4f0f341f01 Merge branch 'dockerfile-changes' into 'main'
Update dockerfile for tribes

See merge request soapbox-pub/ditto!530
2024-10-03 20:55:09 +00:00
Siddharth Singh
7107e38915
fix port nonsense 2024-10-04 02:14:58 +05:30
Siddharth Singh
baae2974f3
typo fix 2024-10-04 02:14:21 +05:30
Siddharth Singh
eac375b99d
update dockerfile for tribes 2024-10-04 02:06:10 +05:30
Alex Gleason
cb78799997 Merge branch 'ts-ext' into 'main'
Treat .ts links in statuses as application/typescript

Closes #241

See merge request soapbox-pub/ditto!529
2024-10-03 18:07:00 +00:00
Alex Gleason
bd3d7fda94
Treat .ts links in statuses as application/typescript
Fixes https://gitlab.com/soapbox-pub/ditto/-/issues/241
2024-10-03 13:02:40 -05:00
Alex Gleason
dfae0b15c7 Merge branch 'use-sticky-notes-zap' into 'main'
refactor(lnurl): use Stickynotes instead of legacy Debug

See merge request soapbox-pub/ditto!528
2024-10-03 16:07:53 +00:00
P. Reis
e42c047362 refactor: use Stickynotes instead of legacy Debug 2024-10-03 12:56:40 -03:00
P. Reis
ab85360d2f refactor: move getConfigs() function and frontendConfig logic to 'src/utils/frontendConfig.ts' 2024-10-03 11:17:21 -03:00
Alex Gleason
76fceace7c Merge branch 'hints' into 'main'
Improve relay/pubkey hints when creating a status

See merge request soapbox-pub/ditto!527
2024-10-03 03:57:21 +00:00
Alex Gleason
7f8697f4f3
Fix zap tag logic 2024-10-02 22:52:07 -05:00
Alex Gleason
031297f253
Improve relay/pubkey hints when creating a status 2024-10-02 22:46:52 -05:00
Alex Gleason
4561ec0d00
Store the Push Subscription in the database 2024-10-02 22:20:47 -05:00
Alex Gleason
049d99af9b
Merge remote-tracking branch 'origin/main' into push 2024-10-02 19:26:37 -05:00
Alex Gleason
33980d54f3 Merge branch 'hash-tokens' into 'main'
Rework auth tokens table to use hashed/encrypted data

Closes #234

See merge request soapbox-pub/ditto!526
2024-10-02 23:50:51 +00:00
Alex Gleason
ff361a4106
Recreate nip46_tokens in down migration 2024-10-02 18:34:19 -05:00
Alex Gleason
432857c2ff
Rework auth tokens table to use hashed/encrypted data 2024-10-02 18:28:24 -05:00
Alex Gleason
e73a8d71dc
auth: add encryptSecretKey & decryptSecretKey functions 2024-10-02 17:56:30 -05:00
Alex Gleason
70f56af281
Add auth utils for generating/hashing/encoding/decoding tokens 2024-10-02 15:05:37 -05:00
Alex Gleason
1d2bf07460
Remove unused nostr-relaypool library 2024-10-02 13:44:50 -05:00
Alex Gleason
23bedd82a0
utils: remove unused sha256 text function 2024-10-02 13:36:00 -05:00
Alex Gleason
a10e810068
Create push_subscriptions table 2024-10-02 13:14:37 -05:00
Alex Gleason
c5bcf1d4a3 Merge branch 'ditto-instance-kind-0' into 'main'
Add script for setting Ditto instance kind 0

See merge request soapbox-pub/ditto!525
2024-10-02 15:40:09 +00:00
Siddharth Singh
3df1fe4d3a
neatness 2024-10-02 20:53:57 +05:30
Siddharth Singh
a5762628a5
add script for setting ditto kind 0 2024-10-02 20:47:46 +05:30
P. Reis
e7f5e563f5 feat: load dotenv in script/trends.ts 2024-10-01 13:59:21 -03:00
P. Reis
7c29c81226 test: pass languagesIds in getTrendingTagValues() function 2024-10-01 13:58:51 -03:00
P. Reis
d8b2c057b0 feat: make trends fast again
remove previous JOIN, now if a language is set, it will do '''query.where('trends.value', 'in', languagesIds);''', which is faster than a JOIN
2024-10-01 13:58:08 -03:00
P. Reis
b549cdef53 refactor: rename TREND_LANGUAGES to DITTO_LANGUAGES 2024-10-01 13:52:30 -03:00
Alex Gleason
141d5be999
Merge remote-tracking branch 'origin/main' into push 2024-09-30 20:33:41 -05:00
Alex Gleason
50733d6e0b
Retain uploads for 6 hours 2024-09-30 20:33:17 -05:00
Alex Gleason
bece384124
Add Web Push skeleton 2024-09-30 19:12:53 -05:00
P. Reis
c0d9a90bfa refactor: remove un-used variable 2024-09-30 14:09:19 -03:00
P. Reis
5e23f4d636 test: trends without language and with language 2024-09-30 14:03:22 -03:00
P. Reis
61bc57c778 feat: support trendings by language 2024-09-30 14:02:12 -03:00
Alex Gleason
52b02043d9
Upgrade @gleasonator/policy in deno.lock 2024-09-30 11:54:41 -05:00
P. Reis
b33a6cdfe0 feat: add TREND_LANGUAGES environment variable 2024-09-30 13:53:30 -03:00
Alex Gleason
be5350a0a5 Merge branch 'manifest' into 'main'
Add initial webmanifest controller

See merge request soapbox-pub/ditto!521
2024-09-26 18:57:31 +00:00
Alex Gleason
64a6d7170c
Add initial webmanifest controller 2024-09-26 13:50:51 -05:00
Alex Gleason
4da82e9484
Update @gleasonator/policy in deno.lock 2024-09-25 16:47:30 -05:00
Alex Gleason
2fcaa9fe31
publicTimelineController: add conditional around filters.search assignment 2024-09-25 15:16:17 -05:00
Alex Gleason
68ab9f638c Merge branch 'pglite-policy' into 'main'
Fix PGlite in local development

See merge request soapbox-pub/ditto!520
2024-09-25 20:15:46 +00:00
Alex Gleason
2fdf68552c Merge branch 'filter-global-feed-by-language' into 'main'
feat: filter global and local feed by language

Closes #223

See merge request soapbox-pub/ditto!519
2024-09-25 20:12:17 +00:00
Alex Gleason
ff658cf496
policy: fix Error constructor 2024-09-25 15:10:12 -05:00
P. Reis
8ad101ce7b refactor: remove max(2) in languageSchema 2024-09-25 17:03:30 -03:00
Alex Gleason
f50b41f22b
Refactor PolicyWorker error handling 2024-09-25 15:01:40 -05:00
P. Reis
77f5965cdc refactor: return zod errors in publicTimelineController 2024-09-25 16:52:54 -03:00
P. Reis
12aaf8c678 refactor: use languageSchema in createStatusSchema 2024-09-25 16:51:59 -03:00
P. Reis
92aaca0d91 feat: create languageSchema 2024-09-25 16:51:23 -03:00
Alex Gleason
350671db47
DittoPglite: prevent starting PGlite instances in worker threads 2024-09-25 14:31:28 -05:00
Alex Gleason
606aeb3236
test: drop postgres tables dynamically 2024-09-25 13:13:58 -05:00
P. Reis
dac11a9055 feat: filter global and local feed by language
add a 'language' field in publicQuerySchema
2024-09-25 13:56:14 -03:00
Alex Gleason
f44b9267ad
Remove unused utils/ipfs.ts 2024-09-25 09:47:51 -05:00
Alex Gleason
657a513cf1 Merge branch 'pglite-0.2.8' into 'main'
Upgrade to pglite v0.2.8

See merge request soapbox-pub/ditto!518
2024-09-25 14:14:14 +00:00
Alex Gleason
f1828bfb52
Upgrade to pglite v0.2.8 2024-09-25 09:10:00 -05:00
Alex Gleason
3ff3ba81b7 Merge branch 'zap-notification-streaming' into 'main'
feat: zap notification in streaming

Closes #204

See merge request soapbox-pub/ditto!490
2024-09-24 22:50:35 +00:00
Alex Gleason
be88e0bc2e Merge branch 'pipeline-stats' into 'main'
pipeline: insert event even if stats fail

Closes #221 and #227

See merge request soapbox-pub/ditto!517
2024-09-24 21:54:32 +00:00
Alex Gleason
9f02215c04
Rethrow the error 2024-09-24 16:20:42 -05:00
Alex Gleason
3469374d8e
pipeline: insert event even if stats fail 2024-09-24 16:15:26 -05:00
P. Reis
b81ae3f043 Merge branch 'main' into zap-notification-streaming 2024-09-24 18:12:28 -03:00
Alex Gleason
d72ec843cf
Add relay connections metrics 2024-09-23 22:28:01 -05:00
Alex Gleason
fc73cb2961
Upgrade Nostrify 2024-09-23 22:16:03 -05:00
Alex Gleason
6a8b22d018
metrics: improve fetch response metrics 2024-09-23 21:29:50 -05:00
Alex Gleason
f8fcb9ac77 Merge branch 'policy-signal' into 'main'
Pass signal into policy

See merge request soapbox-pub/ditto!514
2024-09-23 23:10:00 +00:00
Alex Gleason
fe7a8aa8a7
Merge remote-tracking branch 'origin/main' into policy-signal 2024-09-23 18:06:11 -05:00
Alex Gleason
6d0611dafe
Pass signal into policy 2024-09-23 18:04:12 -05:00
Alex Gleason
3dd53f71e9 Merge branch 'catch-update-stats' into 'main'
fix: catch updateStats() function

Closes #221

See merge request soapbox-pub/ditto!513
2024-09-23 22:53:41 +00:00
P. Reis
42371bcc31 fix: catch updateStats() function 2024-09-23 17:47:55 -03:00
Alex Gleason
e0b966bb6d Merge branch 'add-sticky-to-relay' into 'main'
Sticky Notes: add "ditto:relay" in /relay endpoint

See merge request soapbox-pub/ditto!512
2024-09-23 18:50:58 +00:00
P. Reis
92d8f9b8c2 refactor(pipeline.ts): use correct Stickynotes, and not legacy Debug 2024-09-23 15:36:05 -03:00
P. Reis
60ebff45d5 refactor: use correct Stickynotes, and not legacy Debug 2024-09-23 15:33:14 -03:00
P. Reis
1a1adc1654 feat: add ditto:relay in /relay - sticky notes 2024-09-23 14:47:17 -03:00
Alex Gleason
70e27b04f4 Merge branch 'deno-2.0' into 'main'
Ugrade to Deno 2.0

See merge request soapbox-pub/ditto!511
2024-09-22 23:35:07 +00:00
Alex Gleason
8267916466
Add back pipeline test 2024-09-22 18:01:07 -05:00
Alex Gleason
ebce4a8b1d
Fix a few more type errors, whoops 2024-09-22 17:46:21 -05:00
Alex Gleason
b6e7a5529f
Downgrade GitLab CI to rc3 for now 2024-09-22 17:38:31 -05:00
Alex Gleason
cd66234af7
Ugrade to Deno 2.0 2024-09-22 17:35:04 -05:00
Alex Gleason
cccb3ad8d7 Merge branch 'fix-lru' into 'main'
SimpleLRU: fix repeated calls fetching

See merge request soapbox-pub/ditto!510
2024-09-22 21:13:04 +00:00
Alex Gleason
6745e96c64
SimpleLRU: fix repeated calls fetching 2024-09-22 16:06:10 -05:00
Alex Gleason
ce562b3b6a
Upgrade @gleasonator/policy in deno.lock 2024-09-22 14:41:34 -05:00
Alex Gleason
dee635235b Merge branch 'fix-streaming' into 'main'
pipeline: fix events not being pushed through streaming API

Closes #206

See merge request soapbox-pub/ditto!509
2024-09-22 16:56:08 +00:00
Alex Gleason
c4391ccd99
pipeline: fix events not being pushed through streaming API
Fixes https://gitlab.com/soapbox-pub/ditto/-/issues/206
2024-09-22 11:49:37 -05:00
Alex Gleason
2587b57794
grafana: add streaming API section 2024-09-21 22:27:00 -05:00
Alex Gleason
1be8fcbcdf Merge branch 'streaming-metrics' into 'main'
Streaming metrics

See merge request soapbox-pub/ditto!508
2024-09-22 03:17:07 +00:00
Alex Gleason
195cf9f44e
metrics: add messages sent and received by streaming API 2024-09-21 21:44:24 -05:00
Alex Gleason
fc7228e183
Streaming metrics 2024-09-21 21:40:52 -05:00
Alex Gleason
323d97e5e0
Upgrade @gleasonator/policy in deno.lock 2024-09-21 21:01:11 -05:00
Alex Gleason
4598782a38
Upgrade @gleasonator/policy in deno.lock 2024-09-21 18:12:57 -05:00
Alex Gleason
7ec4be5011
Add gleasonator-policy 0.6.0 to deno.lock 2024-09-21 16:56:01 -05:00
Alex Gleason
6f487c0891
grafana: fix datasource variables 2024-09-21 15:10:59 -05:00
Alex Gleason
7d1b64c234 Merge branch 'relay-conn-metrics' into 'main'
relay: fix connection metrics

Closes #203

See merge request soapbox-pub/ditto!507
2024-09-21 20:09:57 +00:00
Alex Gleason
5a0a2087e5
relay: fix connection metrics 2024-09-21 14:48:50 -05:00
Alex Gleason
9c9b87bc94
grafana: make caches into gauges 2024-09-21 11:36:08 -05:00
Alex Gleason
15372ceb43 Merge branch 'inc-cache' into 'main'
Make cache settings configurable, increase default values

See merge request soapbox-pub/ditto!506
2024-09-20 18:29:29 +00:00
Alex Gleason
454b362825
deno lint 2024-09-20 13:24:33 -05:00
Alex Gleason
807bc78472
Let caches be configurable 2024-09-20 13:22:45 -05:00
Alex Gleason
099fec6e31
Increase nip05 cache to 3000, link previews to 1000 2024-09-20 13:13:26 -05:00
Alex Gleason
efb37701f0
grafana: add cache section 2024-09-20 13:03:30 -05:00
Alex Gleason
7c45d13849 Merge branch 'cache-metrics' into 'main'
Add cache metrics

See merge request soapbox-pub/ditto!505
2024-09-20 17:41:12 +00:00
Alex Gleason
58bf286ce0
Add cache metrics 2024-09-20 12:34:54 -05:00
Alex Gleason
084e3c8341
note: test that mentions with commas get parsed correctly 2024-09-20 11:46:14 -05:00
Alex Gleason
80302b3915 Merge branch 'stats64' into 'main'
Use char(64) for stats primary keys

See merge request soapbox-pub/ditto!504
2024-09-20 15:37:35 +00:00
Alex Gleason
f0c8096498
stats64: delete invalid rows first 2024-09-20 10:07:50 -05:00
Alex Gleason
2b2cdca282
Use char(64) for stats primary keys 2024-09-20 09:58:46 -05:00
Alex Gleason
e27c1519fb Merge branch 'followers-index' into 'main'
author_stats: add index on followers_count

See merge request soapbox-pub/ditto!503
2024-09-20 14:20:09 +00:00
Alex Gleason
c582b1c520
author_stats: add index on followers_count 2024-09-20 09:16:09 -05:00
Alex Gleason
ab727c3940 Merge branch 'move-author-search-to-author-stats' into 'main'
Order search by followers count & Move author search to author stats

Closes #140

See merge request soapbox-pub/ditto!500
2024-09-20 13:57:31 +00:00
Alex Gleason
54d7a12263 Merge branch 'admin-skip-policy' into 'main'
pipeline: let ditto admin skip the policy

See merge request soapbox-pub/ditto!502
2024-09-20 13:54:57 +00:00
P. Reis
b13e924001 fix: build search and also return it in countAuthorStats() function 2024-09-20 10:25:47 -03:00
P. Reis
578f269a65 refactor: countAuthorStats() function does not return search 2024-09-20 09:55:25 -03:00
Alex Gleason
5dca8d4950
pipeline: let ditto admin skip the policy 2024-09-19 21:57:59 -05:00
Alex Gleason
cc2b5cf66a Merge branch 'firehose-kinds' into 'main'
Add FIREHOSE_KINDS variable

See merge request soapbox-pub/ditto!501
2024-09-20 02:56:03 +00:00
Alex Gleason
b53c6dab62
Add FIREHOSE_KINDS variable 2024-09-19 21:51:48 -05:00
P. Reis
ebeb150463 refactor: use search in author_stats 2024-09-19 19:37:13 -03:00
P. Reis
1b6e9160ec test: update to use author_stats table 2024-09-19 19:36:44 -03:00
P. Reis
2727523540 feat: order search by followers count also 2024-09-19 19:36:13 -03:00
P. Reis
f063da1b86 refactor: add search field to AuthorStatsRow, remove AuthorSearch interface 2024-09-19 19:35:38 -03:00
P. Reis
017c17c8a2 refactor: remove author_search table, put search in author_stats 2024-09-19 19:35:05 -03:00
Alex Gleason
d1f452d87b Merge branch 'fix-pg-trgm-operator' into 'main'
Fix search, use word_similarity operator

Closes #213

See merge request soapbox-pub/ditto!498
2024-09-19 13:58:45 +00:00
P. Reis
2f27e22b4c test(getPubkeysBySearch): change search query 2024-09-19 10:15:41 -03:00
P. Reis
148e714863 fix(pg_trgm): use <% instead of % 2024-09-19 10:07:04 -03:00
P. Reis
aa07809e3f Merge branch 'main' into zap-notification-streaming 2024-09-18 18:32:35 -03:00
Alex Gleason
ee68fbad48 Merge branch 'domain-search-perf' into 'main'
EventsDB: fix domain search performance (also allow searching by multiple languages/domains)

See merge request soapbox-pub/ditto!497
2024-09-18 18:46:37 +00:00
Alex Gleason
5ecf016cb9
EventsDB: fix domain search performance (also allow searching by multiple languages/domains) 2024-09-18 13:42:43 -05:00
Alex Gleason
f55a6d515a Merge branch 'enhance-profile-search-again' into 'main'
feat: show users you follow first in search

Closes soapbox#1724

See merge request soapbox-pub/ditto!494
2024-09-18 18:02:15 +00:00
Alex Gleason
8890f6bce5
searchEvents: fix account_id, simplify code 2024-09-18 12:58:17 -05:00
P. Reis
4ae17c4993 refactor: make getPubkeysBySearch() function return Set<string> 2024-09-18 14:15:18 -03:00
P. Reis
f1c0d8c18f refactor(getPubkeysBySearch): rename followList to followedPubkeys 2024-09-18 11:30:41 -03:00
P. Reis
373e9ca6d8 Merge branch 'main' into zap-notification-streaming 2024-09-17 17:06:45 -03:00
P. Reis
f73b20bf03 refactor: make getPubkeysBySearch() function use set of strings Set<string> 2024-09-17 14:50:33 -03:00
P. Reis
47c1d290b0 Merge branch 'main' into enhance-profile-search-again 2024-09-17 14:42:15 -03:00
Alex Gleason
c67d27e580 Merge branch 'refactor-queries-ts' into 'main'
refactor: getFollowedPubkeys() and getFeedPubkeys() functions return Set<string>

See merge request soapbox-pub/ditto!496
2024-09-17 17:40:39 +00:00
P. Reis
19069c0417 refactor: return set in a different way 2024-09-17 14:37:04 -03:00
P. Reis
7eab62b9a9 refactor: getFollowedPubkeys() and getFeedPubkeys() functions return Set<string> 2024-09-17 14:02:46 -03:00
Alex Gleason
8ba9e6e8b8 Merge branch 'nip70' into 'main'
Block NIP-70 protected events

See merge request soapbox-pub/ditto!495
2024-09-17 14:48:31 +00:00
Alex Gleason
d32b12c814
Block NIP-70 protected events 2024-09-17 09:44:46 -05:00
P. Reis
8cd212e407 test: add missing argument in getPubkeysBySearch() function 2024-09-17 11:09:39 -03:00
P. Reis
52001373e0 feat: show users you follow first in search
getPubkeysBySearch() function refactored to accept a followList argument
2024-09-17 11:04:27 -03:00
Alex Gleason
e0dee33aec Merge branch 'pglite-debug' into 'main'
Add PGLITE_DEBUG environment variable

See merge request soapbox-pub/ditto!493
2024-09-16 17:36:50 +00:00
Alex Gleason
8e3ddaa056
Add PGLITE_DEBUG environment variable 2024-09-16 12:31:50 -05:00
P. Reis
2fe6a8fde5 refactor: move getPubkeysBySearch () function to a new location 2024-09-16 14:24:26 -03:00
P. Reis
a18b049eb7 feat: make notifications great again
it works the same as before, but with way less code
2024-09-16 14:08:45 -03:00
P. Reis
9b66499df3 fix: get zap recipient in gatherAuthors() function
this is needed to work correctly in notifications
2024-09-16 14:00:12 -03:00
P. Reis
af13614f1a test(hydrate): expect zap_message also 2024-09-16 13:31:49 -03:00
P. Reis
04a9a83fed feat: hydrate zap_message 2024-09-16 13:30:43 -03:00
P. Reis
7fea333483 feat(DittoEvent): add zap_message field 2024-09-16 13:30:01 -03:00
P. Reis
07c364b829 test(hydrate): add zap receipt, kind 9735 2024-09-16 13:17:42 -03:00
P. Reis
4f0f1182b8 test(fixtures): jack zaps patrick 2024-09-16 13:15:58 -03:00
P. Reis
10f30b3661 test(fixtures): patrick kind 1, post zapped 2024-09-16 13:15:43 -03:00
P. Reis
5caa482806 test(fixtures): patrick kind 0 2024-09-16 13:15:21 -03:00
P. Reis
516866a905 test(fixtures): jack kind 0 2024-09-16 13:15:05 -03:00
P. Reis
a2077e3d40 feat: hydrate zap receipt kind 9735 - gatherZapSender, gatherZapped 2024-09-16 13:13:55 -03:00
P. Reis
6e2508063b feat(DittoEvent): add zapped, zap_sender & zap_amount 2024-09-16 13:10:10 -03:00
P. Reis
8b5940298c Merge branch 'main' into zap-notification-streaming 2024-09-16 09:18:40 -03:00
Alex Gleason
4d0ae401b3 Merge branch 'fix-postgres-password-input' into 'main'
Change setup.ts to use password input instead of plaintext

See merge request soapbox-pub/ditto!492
2024-09-16 00:28:00 +00:00
Siddharth Singh
0dcb1965be
Change setup.ts to use password input instead of plaintext 2024-09-16 05:52:51 +05:30
Alex Gleason
a87497380a
Make pipeline query easier to look at 2024-09-15 19:22:14 -05:00
Alex Gleason
718795fcd1 Merge branch 'fix-postgresjs-error' into 'main'
Fix ambiguous postgres.js errors

Closes #205

See merge request soapbox-pub/ditto!491
2024-09-16 00:03:39 +00:00
Alex Gleason
5a98ba86bf
Fix ambiguous postgres.js errors 2024-09-15 18:58:34 -05:00
Alex Gleason
8510f22d1b
Only save the nip05 in author search if it's valid 2024-09-15 18:33:16 -05:00
Alex Gleason
a8df213aec Merge branch 'language-detection' into 'main'
Support NIP-50 language extension

See merge request soapbox-pub/ditto!489
2024-09-15 23:11:30 +00:00
Alex Gleason
394021e485
Don't use semi-colons in migration 2024-09-15 17:38:16 -05:00
Alex Gleason
642ecfd36f
Rename language migration to 033 2024-09-15 17:26:02 -05:00
Alex Gleason
8da223ad6c
Merge remote-tracking branch 'origin/main' into language-detection 2024-09-15 17:25:36 -05:00
Alex Gleason
580e773bfc Merge branch 'enchance-profile-search' into 'main'
Enchance profile search

Closes soapbox#1710

See merge request soapbox-pub/ditto!488
2024-09-15 21:46:49 +00:00
P. Reis
cbc1691002 feat: zap notification in streaming 2024-09-15 18:34:11 -03:00
P. Reis
dc69f21e0b refactor: write map function in a cleaner way 2024-09-15 17:46:10 -03:00
P. Reis
c5711ea071 refactor(accountSearchController): only reassign events if event is undefined 2024-09-15 17:42:58 -03:00
P. Reis
ed74b2464a refactor: write it like a normal if statement 2024-09-15 17:42:26 -03:00
P. Reis
3b8a800cd2 refactor(search enchance): map over pubkeys instead of events 2024-09-15 17:27:56 -03:00
P. Reis
d7ae3722c8 refactor: insert each event per iteration in for loop - db:populate-search 2024-09-15 16:52:49 -03:00
Alex Gleason
f8902760ce
Make the language index a compound index 2024-09-15 13:37:23 -05:00
Alex Gleason
eede3909b1
Upgrade @nostrify/db to fix table joins 2024-09-15 13:05:54 -05:00
Alex Gleason
c24d11c6f3
Support NIP-50 language extension 2024-09-15 12:40:58 -05:00
P. Reis
f99ea7c33f refactor(getPubkeysBySearch): cast as string 2024-09-13 18:57:47 -03:00
P. Reis
197b2c8c8b refactor(populate search script): use store.req instead of streaming 2024-09-13 18:49:20 -03:00
P. Reis
b3e56320a0 feat(accountSearchController): return accounts in autocomplete form 2024-09-13 18:41:20 -03:00
P. Reis
6387ee440c feat: return multiple accounts in searchController 2024-09-13 16:36:01 -03:00
P. Reis
69c2158131 refactor: return ordered accounts by similarity relevance in searchEvents() function 2024-09-13 16:20:56 -03:00
P. Reis
be76197e3a refactor: remove handleAuthorSearch() function and put its logic inside parseMetadata() function 2024-09-13 16:20:52 -03:00
P. Reis
935cc7c5a5 refactor: remove NIP-50 search if looking for accounts, use same filter 2024-09-13 14:33:34 -03:00
P. Reis
a974f4230d Merge branch 'main' into enchance-profile-search 2024-09-13 10:34:45 -03:00
P. Reis
24d909fd28 feat: create script to populate author_search table 2024-09-13 10:34:15 -03:00
P. Reis
a6f1098bc6 test: getPubkeysBySearch() function 2024-09-13 10:32:05 -03:00
P. Reis
e1cd1777e3 test: add author_search table in createTestDB to drop it after use 2024-09-13 10:30:10 -03:00
P. Reis
9d2667679f feat(pipeline.ts): create handleAuthorSearch() function 2024-09-13 10:28:54 -03:00
P. Reis
c03ea07dcb feat: create getPubkeysBySearch() function and use it inside searchEvents() function 2024-09-13 10:27:12 -03:00
P. Reis
b5aefdd93e feat: add pg_trgm extension in PGlite constructor 2024-09-13 10:24:33 -03:00
P. Reis
8bc8712cf3 feat: create and add author_search interface to DittoTables 2024-09-13 10:23:08 -03:00
P. Reis
40c187680e feat: create author_search table 2024-09-13 10:22:05 -03:00
Alex Gleason
b384fcf572
Make EventsDB extend NPostgres 2024-09-12 17:22:44 -05:00
Alex Gleason
4955be4104 Merge branch 'stats-inflation' into 'main'
Fix stat inflation

See merge request soapbox-pub/ditto!487
2024-09-12 18:48:38 +00:00
Alex Gleason
1732b69022
Remove unused Storages.close method 2024-09-12 13:39:02 -05:00
Alex Gleason
a0fd702e09
Revert DittoPglite 2024-09-12 13:38:00 -05:00
Alex Gleason
8316762370
Remove this DittoExit stuff (since I'm not convinced it's needed) 2024-09-12 13:37:21 -05:00
Alex Gleason
b3cfd5e12c
waitReady is not actually needed 2024-09-12 13:17:21 -05:00
Alex Gleason
c50c63f954
pipeline: purifyEvent before passing it to storage 2024-09-12 13:10:36 -05:00
Alex Gleason
fc912f185e
Gracefully start and exit the database 2024-09-12 13:03:23 -05:00
Alex Gleason
d67f2a27ea
stats: use the NPostgres transaction method to avoid transactions within transactions 2024-09-12 11:30:57 -05:00
Alex Gleason
55ee8eaf74
Fix stat inflation 2024-09-12 11:09:54 -05:00
Alex Gleason
593cedba06
grafana: add API endpoints row 2024-09-11 21:34:16 -05:00
Alex Gleason
f7ee59146e
Clean up config 2024-09-11 18:30:23 -05:00
Alex Gleason
20d1f885ac
Upgrade gleasonator-policy in deno.lock 2024-09-11 16:53:02 -05:00
Alex Gleason
b449b17fbe
Add updated gleasonator-policy to deno.lock 2024-09-11 16:11:09 -05:00
Alex Gleason
6b66e61ee9
PolicyWorker: mock Deno.env 2024-09-11 14:34:41 -05:00
Alex Gleason
a1585d81aa Merge branch 'store-policy' into 'main'
Expose db to Policy script

See merge request soapbox-pub/ditto!486
2024-09-11 19:21:11 +00:00
Alex Gleason
cae0f492f3
Let PolicyWorker run in sandbox with store 2024-09-11 14:04:11 -05:00
Alex Gleason
ebc0250d81
DittoDB.getInstance() -> Storages.kysely() 2024-09-11 13:23:06 -05:00
Alex Gleason
d2fb3fd253
Make EventsDB not rely on Conf 2024-09-11 13:06:20 -05:00
Alex Gleason
624b6b278e Merge branch 'rm-sqlite' into 'main'
Remove SQLite support, simplify database code

See merge request soapbox-pub/ditto!485
2024-09-11 17:07:08 +00:00
Alex Gleason
fad40f1c30
createTestDB: don't accept an arg 2024-09-11 11:57:28 -05:00
Alex Gleason
f3ae200833
Simplify database interfaces, make tests use pglite 2024-09-11 11:48:58 -05:00
Alex Gleason
dc8d09a9da
Remove SQLite support 2024-09-11 11:08:33 -05:00
Alex Gleason
f76d0af16d
Add TEST_DATABASE_URL env, change database defaults 2024-09-11 10:28:06 -05:00
Alex Gleason
a888f43288 Merge branch 'pglite' into 'main'
Add support for pglite

See merge request soapbox-pub/ditto!483
2024-09-10 21:12:47 +00:00
Alex Gleason
25a8f27cb7
ci: upgrade deno to v1.46.3 2024-09-10 16:01:13 -05:00
Alex Gleason
6a14272184
Make pglite work 2024-09-10 16:00:16 -05:00
Alex Gleason
9331ab4ac1
grafana: add system usage, break up into rows 2024-09-08 13:31:09 -05:00
Alex Gleason
ca1455c59a Merge branch 'render-unknown' into 'main'
Don't limit statuses to kind 1

See merge request soapbox-pub/ditto!484
2024-09-08 14:08:37 +00:00
Alex Gleason
2309fd72d1
Don't limit statuses to kind 1 2024-09-08 09:05:23 -05:00
Alex Gleason
8a94e8deb3
grafana: fix db effort query 2024-09-08 05:38:33 -05:00
Alex Gleason
819957da49
Upgrade kysely-pglite 2024-09-07 20:56:50 -05:00
Alex Gleason
69329674e1
Add support for pglite 2024-09-07 16:38:28 -05:00
Alex Gleason
044708d49f Merge branch 'fetch-ua' into 'main'
Fetch link previews with facebookexternalhit instead of WhatsApp/2 by default, make it configurable

See merge request soapbox-pub/ditto!482
2024-09-07 18:12:33 +00:00
Alex Gleason
a19b7fbe9e
Fetch link previews with facebookexternalhit instead of WhatsApp/2 by default, make it configurable 2024-09-07 13:09:10 -05:00
Alex Gleason
3af56995af Merge branch 'ansible' into 'main'
Add ansible playbook to update multiple Ditto servers at once

See merge request soapbox-pub/ditto!481
2024-09-07 16:01:24 +00:00
Alex Gleason
23f6038427
Add ansible playbook to update multiple Ditto servers at once 2024-09-07 10:54:48 -05:00
Alex Gleason
ac4a63bdcc
deno task soapbox: don't prompt to overwrite 2024-09-07 10:43:01 -05:00
Alex Gleason
fac484c651 Merge branch 'attachments-simplify' into 'main'
Remove unattached_media table, switch to LRUCache, fix uploads in random order

Closes #192

See merge request soapbox-pub/ditto!480
2024-09-07 15:35:44 +00:00
Alex Gleason
99a25e1e18
media: fix setting description 2024-09-07 10:32:14 -05:00
Alex Gleason
8efd6fbb20
Remove unattached_media table, replace with LRUCache, fix media upload order problem 2024-09-07 10:24:56 -05:00
Alex Gleason
85000cd00e Merge branch 'mention-link-fix' into 'main'
Fix rendering mentions inside of URLs

See merge request soapbox-pub/ditto!479
2024-09-07 14:44:56 +00:00
Alex Gleason
ddba16551a
Fix rendering mentions inside of URLs 2024-09-07 09:41:43 -05:00
Alex Gleason
1a98049ee8 Merge branch 'prom-metrics-best' into 'main'
Update Prometheus metrics to conform to best practices

See merge request soapbox-pub/ditto!478
2024-09-07 14:15:07 +00:00
Alex Gleason
537de85421
Add grafana dashboard.json 2024-09-07 09:02:14 -05:00
Alex Gleason
4a578528f5
Add back pool size gauge 2024-09-07 09:00:18 -05:00
Alex Gleason
5454942a2c
Update Prometheus metrics to conform to best practices 2024-09-07 08:52:02 -05:00
Alex Gleason
a7292b1b8d Merge branch 'fix-zap-notification' into 'main'
fix(zap notification): put kind 9735 in the first filter

See merge request soapbox-pub/ditto!477
2024-09-06 05:43:01 +00:00
P. Reis
a8900b3217 fix(zap notification): put kind 9735 in the first filter 2024-09-05 18:43:02 -03:00
Alex Gleason
4373a1eea9 Merge branch 'zap-notification' into 'main'
Implement zap notifications + Fix notification pagination

Closes #193

See merge request soapbox-pub/ditto!474
2024-09-05 20:14:54 +00:00
P. Reis
486dff83b9 fix: pass parameters params in ditto:zap notification 2024-09-03 22:24:01 -03:00
P. Reis
6d9d2fd42a fix: get event id from max_id
sometimes the 'max_id' format can come as `${created_at}-${id}`
so if that's the case, we split by the - (minus) character
2024-09-03 22:23:55 -03:00
Alex Gleason
3fa97c0533 Merge branch 'fix-streaming-self' into 'main'
streaming: don't notify self of own post

See merge request soapbox-pub/ditto!475
2024-09-02 23:11:41 +00:00
Alex Gleason
7c319c6ff0
streaming: don't notify self of own post 2024-09-03 00:58:35 +02:00
Alex Gleason
e40201ffb5 Merge branch 'clean-error-types' into 'main'
feat: add clean type errors task

See merge request soapbox-pub/ditto!472
2024-09-02 22:56:32 +00:00
P. Reis
1777224f97 refactor: rename clean:type-errors to clean:deps 2024-09-02 10:00:23 -03:00
P. Reis
8e8f8767b4 Merge branch 'main' into zap-notification 2024-09-02 09:54:45 -03:00
P. Reis
96e99f38c4 feat(views): render and return zap notification 2024-09-02 09:54:24 -03:00
P. Reis
729471d692 feat(notifications api): implement zap notification
calls database for zap events
2024-09-02 09:53:42 -03:00
Alex Gleason
b909f4e355 Merge branch 'store-alt-text' into 'main'
Store alt text along with other imeta, and render it when requested

Closes #172

See merge request soapbox-pub/ditto!464
2024-09-01 20:10:31 +00:00
Alex Gleason
b271ecc801 Merge branch 'fix-nostrpull-duplicate-events' into 'main'
Handle event insertion errors with warning

Closes #195

See merge request soapbox-pub/ditto!473
2024-09-01 13:56:56 +00:00
Siddharth Singh
e7f5535bd2
handle event insertion errors with warning 2024-09-01 19:15:22 +05:30
P. Reis
8e53da7980 feat: add clean type errors task 2024-08-29 10:22:24 -03:00
Alex Gleason
0b6ca9dfea
Hide non-profile nostr URIs from text 2024-08-28 21:24:50 +02:00
Alex Gleason
ba77787767
Test and fix parsing of URLs 2024-08-28 21:19:07 +02:00
Alex Gleason
7a2a8bd4f5
Wrap URL in a try-catch 2024-08-28 21:15:43 +02:00
Alex Gleason
043e579c10 Merge branch 'fix-url' into 'main'
Fix parsing of regular URLs

See merge request soapbox-pub/ditto!471
2024-08-28 19:07:37 +00:00
Alex Gleason
a63b838195
Fix parsing of regular URLs 2024-08-28 21:02:52 +02:00
Alex Gleason
cde70e4c8f Merge branch 'fix-apostrophe-issue' into 'main'
Fixed apostrophe issue

Closes #190

See merge request soapbox-pub/ditto!470
2024-08-28 17:49:26 +00:00
Alex Gleason
f9d1eed4dd
Remove unnecessary escape characters 2024-08-28 19:46:19 +02:00
Alex Gleason
c2ea4cbfd5
Fix parsing bech32 with apostrophe 2024-08-28 19:38:06 +02:00
danidfra
8d8211de09 Fixed apostrophe issue 2024-08-28 14:01:26 -03:00
Alex Gleason
a505372bd1 Merge branch 'resp-method' into 'main'
metrics: track response method

See merge request soapbox-pub/ditto!469
2024-08-28 12:44:05 +00:00
Alex Gleason
f730771d72
metrics: track response method 2024-08-28 14:40:45 +02:00
Alex Gleason
0d44932a04 Merge branch 'message-zap-split' into 'main'
feat: implement fifth parameter in zap tag

See merge request soapbox-pub/ditto!468
2024-08-27 22:04:05 +00:00
P. Reis
7d9f874cdf feat: implement fifth parameter in zap tag 2024-08-27 17:52:51 -03:00
Alex Gleason
4b416e3c66 Merge branch 'update-nostrify' into 'main'
chore: update nostrify to 0.30.1

See merge request soapbox-pub/ditto!467
2024-08-27 18:32:09 +00:00
P. Reis
f96fca835b chore: update nostrify to 0.30.1
other dependencies such as hono were automatically updated as well
2024-08-27 13:40:24 -03:00
Alex Gleason
e286ecc47d Merge branch 'db-export-filters' into 'main'
Allow filtering items exported by `deno task db:export`

Closes #186

See merge request soapbox-pub/ditto!463
2024-08-26 22:14:23 +00:00
Alex Gleason
14a0f38e29 Merge branch 'update-deno-dom' into 'main'
Update deno dom

Closes #194

See merge request soapbox-pub/ditto!466
2024-08-26 18:34:38 +00:00
danidfra
980e904ea7 Update deno-dom 2024-08-26 15:31:03 -03:00
Siddharth Singh
1a38061b34
mediaDescriptionUpdateSchema --> mediaUpdateSchema 2024-08-25 19:48:04 +05:30
Siddharth Singh
7e711aa8a8
updateMediaDescriptionController --> updateMediaController 2024-08-25 19:43:28 +05:30
Siddharth Singh
125dfb54f3
Add tests for db:export filters 2024-08-25 19:41:35 +05:30
Siddharth Singh
f8fae52d5e
fix bug in alt text tagging 2024-08-25 19:13:31 +05:30
Alex Gleason
1e8aeee5a6
nginx: let ditto serve the favicon 2024-08-25 15:49:43 +03:00
Siddharth Singh
1f04a7fcdf
remove debug console.logs 2024-08-25 17:20:25 +05:30
Siddharth Singh
cf4dc8627b
remove unnecessary coalescing 2024-08-25 16:25:36 +05:30
Siddharth Singh
6ff90d63bb
implement PUT /api/v1/media/:id
Adds support for setting image descriptions for accessibility reasons
2024-08-25 16:23:25 +05:30
Siddharth Singh
fb199123be
first working version 2024-08-24 22:56:35 +05:30
Siddharth S Singh
9298bf6608 first commit (nonfunctional) 2024-08-23 16:25:34 +05:30
Alex Gleason
8adc87f1d9 Merge branch 'fe-routes' into 'main'
Add more known frontend routes

See merge request soapbox-pub/ditto!462
2024-08-20 01:17:30 +00:00
Alex Gleason
eb3b442dd4
Add more known frontend routes 2024-08-19 20:13:59 -05:00
Alex Gleason
8702d1ec07 Merge branch 'favicon' into 'main'
Fetch favicon from NIP-05 domain

See merge request soapbox-pub/ditto!461
2024-08-17 14:30:36 +00:00
Alex Gleason
8370b250a2
Add a signal to renderAccount 2024-08-17 09:25:48 -05:00
Alex Gleason
e539a29775
Fetch favicon from NIP-05 domain 2024-08-17 09:21:12 -05:00
Alex Gleason
79ac4ada81 Merge branch 'domain' into 'main'
Add `domain` to Account entity

See merge request soapbox-pub/ditto!460
2024-08-16 18:18:25 +00:00
Alex Gleason
de1c6a05dc
Add domain to Account entity 2024-08-16 13:15:06 -05:00
Alex Gleason
36933484ec Merge branch 'favicon' into 'main'
Use favicon.ico to get instance favicon from NIP-05 of each user

See merge request soapbox-pub/ditto!459
2024-08-16 02:52:29 +00:00
Alex Gleason
a99728981c
Use favicon.ico to get instance favicon from NIP-05 of each user 2024-08-15 21:36:28 -05:00
Alex Gleason
b6f32c4d0f Merge branch 'replaceable-update' into 'main'
Throw when creating a replaceable event that doesn't exist yet

See merge request soapbox-pub/ditto!458
2024-08-15 23:14:13 +00:00
Alex Gleason
4db8b2d4fb
Throw when creating a replaceable event that doesn't exist yet 2024-08-15 18:10:42 -05:00
Alex Gleason
bfa447d250
Upgrade gleasonator-policy in yarn.lock 2024-08-15 14:31:05 -05:00
Alex Gleason
b47cf1c0a5 Merge branch 'splits-flag' into 'main'
Put zap splits behind a feature flag, disabled by default

See merge request soapbox-pub/ditto!457
2024-08-15 03:08:28 +00:00
Alex Gleason
1feeaf7b1e
Put zap splits behind a feature flag, disabled by default 2024-08-14 22:05:17 -05:00
Alex Gleason
3dc6963f5d Merge branch 'deno-1.45.5' into 'main'
Upgrade Deno to v1.45.5

See merge request soapbox-pub/ditto!456
2024-08-13 22:16:57 +00:00
Alex Gleason
bcfd349092
Upgrade Deno to v1.45.5 2024-08-13 17:03:22 -05:00
Alex Gleason
37e122862f Merge branch 'npostgres' into 'main'
Switch to NPostgres

See merge request soapbox-pub/ditto!453
2024-08-13 14:20:18 +00:00
Alex Gleason
1a69df1cd7
Add timeout message to the relay 2024-08-12 23:04:12 -05:00
Alex Gleason
d3f4cd8d8c
Upgrade @nostrify/db to v0.31.2 2024-08-12 21:57:09 -05:00
Alex Gleason
27ba8b071a
pg migration: advise checking out main branch 2024-08-12 16:48:42 -05:00
Alex Gleason
c4064d0fa6
pg migration: 3 days -> several hours 2024-08-12 15:54:56 -05:00
Alex Gleason
e743e14bb1
Fix EventsDB test 2024-08-12 15:45:47 -05:00
Alex Gleason
f116950a83
Fix db:migrate script 2024-08-12 15:25:51 -05:00
Alex Gleason
8a23011392
pg migration: cascade 2024-08-12 15:17:42 -05:00
Alex Gleason
617659c7fd
Fix DittoDB+EventsDB relationship 2024-08-12 15:13:49 -05:00
Alex Gleason
5e4a94457f
Fix tests 2024-08-12 14:57:17 -05:00
Alex Gleason
3a82c98c21
trends: make trends work in Postgres (probably) 2024-08-12 14:48:32 -05:00
Alex Gleason
5c23cb02c2
Add NPostgres migration 2024-08-12 14:37:41 -05:00
Alex Gleason
8dc3b5d5a7
trends: maybe make postgres trends work? 2024-08-11 20:20:31 -05:00
Alex Gleason
8db5489350
Implements trends for SQLite 2024-08-11 19:50:20 -05:00
Alex Gleason
e6b18e7d95
trends: disable for now 2024-08-11 19:12:05 -05:00
Alex Gleason
c8bec9b4b7
Delete unused getUnattachedMedia function 2024-08-11 19:07:27 -05:00
Alex Gleason
552de01a17
Rework DittoDB to return an object 2024-08-11 19:02:27 -05:00
Alex Gleason
f830271ce2
Merge remote-tracking branch 'origin/main' into npostgres 2024-08-11 16:27:59 -05:00
Alex Gleason
e789e08c0f Merge branch 'import-script' into 'main'
Improve performance of import script

See merge request soapbox-pub/ditto!454
2024-08-11 21:11:55 +00:00
Alex Gleason
9f9a07e618
Improve performance of import script 2024-08-11 16:08:15 -05:00
Alex Gleason
300c78ddb1
Upgrade @nostrify/db 2024-08-10 15:44:58 -05:00
Alex Gleason
916b68a3e4
Switch to NPostgres (steamroll SQLite for now) 2024-08-10 13:30:24 -05:00
Alex Gleason
66cfba5535
Remove leading @ from params.acct 2024-08-10 09:58:25 -05:00
Alex Gleason
6657a48a07 Merge branch 'at-match' into 'main'
Fix matching @ routes in app

See merge request soapbox-pub/ditto!452
2024-08-10 02:10:39 +00:00
Alex Gleason
443c8a43f7
Fix matching @ routes in app 2024-08-09 21:07:41 -05:00
Alex Gleason
4bf3096454
errorHandler: don't log timeouts 2024-08-09 13:31:36 -05:00
Alex Gleason
2cbbf2fbe7 Merge branch 'api-err' into 'main'
publishEvent: throw errors

See merge request soapbox-pub/ditto!451
2024-08-09 18:29:35 +00:00
Alex Gleason
abc1a6eb49
EventsDB.event: throw error on insertion 2024-08-09 12:47:59 -05:00
Alex Gleason
9b68d2d08a
publishEvent: throw errors 2024-08-09 12:44:25 -05:00
Alex Gleason
c7a59b50d0
Fix account search 2024-08-08 18:41:29 -05:00
Alex Gleason
800e20a143
Convert og:description to plaintext 2024-08-07 21:36:02 -05:00
Alex Gleason
a46c352d3d Merge branch 'opengraph-metadata' into 'main'
OpenGraph metadata support

Closes #179

See merge request soapbox-pub/ditto!444
2024-08-08 02:22:01 +00:00
Alex Gleason
313c37564c
Add MastodonAttachment type 2024-08-07 21:19:04 -05:00
Alex Gleason
efc121a4ae
Fallback to favicon.ico in link previews 2024-08-07 21:10:31 -05:00
Alex Gleason
15c46ec3f0
Rework nginx file again for link previews 2024-08-07 21:08:03 -05:00
Alex Gleason
2f2fda2ac3
Render OG data on every page 2024-08-07 21:06:51 -05:00
Alex Gleason
5f1b87c3b6
Pretend to be WhatsApp when fetching links 2024-08-07 21:00:07 -05:00
Alex Gleason
ba241f0431
Rework opengraph 2024-08-07 20:47:53 -05:00
Alex Gleason
72970bf480
Code style changes 2024-08-07 19:01:50 -05:00
Alex Gleason
020736fd47
Escape @ in SSR routes 2024-08-07 18:19:39 -05:00
Alex Gleason
349f59cc70
Merge remote-tracking branch 'origin/main' into opengraph-metadata 2024-08-07 18:19:13 -05:00
Alex Gleason
e264d6116c Merge branch 'search-fixes' into 'main'
search: parse bech32 ids from pasted URLs, improve Mastodon API compat

See merge request soapbox-pub/ditto!450
2024-08-07 23:11:20 +00:00
Alex Gleason
2e38a7b9ec
mentionsCompat: wrap each mention in an h-card span 2024-08-07 17:54:45 -05:00
Alex Gleason
ab17be219c
Fix parseNoteContent test 2024-08-07 17:37:44 -05:00
Alex Gleason
2f5b4557b7
compatMentions: remove post author and explicit text mentions 2024-08-07 17:34:36 -05:00
Alex Gleason
529e61be6d
Return properly formatted mentions in Status API 2024-08-07 17:27:22 -05:00
Alex Gleason
a24c119c7b
accountSearchController: actually use the looked up event, whoops 2024-08-07 16:56:15 -05:00
Alex Gleason
fd90c199f5
search: fix lookupPubkey for account search endpoint 2024-08-07 16:44:32 -05:00
Alex Gleason
8f5ec50a25
search: fix nip05 lookups 2024-08-07 16:41:46 -05:00
Alex Gleason
bc603188fa
extractBech32 -> extractIdentifier, support extracting nip05 names 2024-08-07 16:22:10 -05:00
Alex Gleason
d3780037df
search: escape @ signs in matchers 2024-08-07 16:05:04 -05:00
Alex Gleason
ff900341d5
Match every possible goddamn URL format in search 2024-08-07 15:53:59 -05:00
Alex Gleason
dbd40357af
Mimic Mastodon's uri/url fields exactly on Accounts and Statuses 2024-08-07 15:23:33 -05:00
Alex Gleason
8f704e4ea2
Fix account URL lookup with @ in the URL 2024-08-07 14:52:13 -05:00
Alex Gleason
385127761d
Strictly follow Mastodon API's way of only returning one result of a lookup succeeds 2024-08-07 14:41:16 -05:00
Alex Gleason
717fd6bdc9 Merge branch 'zap-tag-endpoint-by-id' into 'main'
Get zap split by post/status id, based in the zap tag

See merge request soapbox-pub/ditto!448
2024-08-07 17:36:09 +00:00
Alex Gleason
cdee2604a1
Apply same search improvements to accountSearchController 2024-08-07 12:31:22 -05:00
P. Reis
10052230e5 refactor: rename getZapSplitsOfStatusController to statusZapSplitsController 2024-08-07 14:24:32 -03:00
Alex Gleason
1efd4fad12
search: parse bech32 ids from pasted URLs 2024-08-07 12:11:13 -05:00
Alex Gleason
b3eb65f5ce Merge branch 'app-redirect' into 'main'
createAppController: parse formdata body

See merge request soapbox-pub/ditto!449
2024-08-07 00:57:51 +00:00
Alex Gleason
9c645cf616
createAppController: parse formdata body 2024-08-06 19:47:26 -05:00
Alex Gleason
d572a43b5a Merge branch 'pagination-compat' into 'main'
Fix Mastodon legacy pagination

See merge request soapbox-pub/ditto!447
2024-08-07 00:24:17 +00:00
Alex Gleason
5d6ab9f63b
Separate listPagination 2024-08-06 19:04:27 -05:00
P. Reis
32cecb5e6b feat: create zap split endpoint based in post/status id 2024-08-06 20:55:40 -03:00
Alex Gleason
d285b7dced
Fix Mastodon legacy pagination 2024-08-06 18:20:26 -05:00
Alex Gleason
09ea0856a6
renderRelationship: delete accidental comment left in 2024-08-06 15:58:04 -05:00
Alex Gleason
6ae48e60e5 Merge branch 'relationships-perf' into 'main'
Optimize relationships database calls

See merge request soapbox-pub/ditto!446
2024-08-06 20:46:09 +00:00
Alex Gleason
41bcd77853
Optimize relationships database calls 2024-08-06 15:34:10 -05:00
Alex Gleason
75935d0b53 Merge branch 'nostrify-30' into 'main'
Upgrade to Nostrify v0.30.0

See merge request soapbox-pub/ditto!445
2024-08-05 20:48:59 +00:00
Alex Gleason
db6417bad9
Upgrade to Nostrify v0.30.0 2024-08-05 15:45:02 -05:00
Siddharth Singh
612c845f95
get rid of r() and RawHtml from html.ts 2024-08-06 01:51:43 +05:30
Siddharth Singh
16f4048604
way better logging 2024-08-06 01:25:39 +05:30
Siddharth Singh
166106b12b
even better kind 0 handling 2024-08-06 00:56:27 +05:30
Alex Gleason
b2136b35e8 Merge branch 'move-get-zap-split-to-new-endpoint' into 'main'
Create getZapSplitsController - Remove zap split from instance V1 endpoint

Closes #182

See merge request soapbox-pub/ditto!442
2024-08-05 19:23:56 +00:00
P. Reis
bce404728b refactor: rename zap_split to dittoZapSplit 2024-08-05 16:20:38 -03:00
Siddharth Singh
2283f64204
regex guard around opengraph routes 2024-08-06 00:45:28 +05:30
Siddharth Singh
f48d8e0a66
use Object.assign to fill template opts 2024-08-06 00:37:14 +05:30
Siddharth Singh
af70065d84
yet another typo fix 2024-08-06 00:32:13 +05:30
Siddharth Singh
4f8ebb95f3
hex regex typo fix 2024-08-06 00:26:04 +05:30
Siddharth Singh
6691908fc4
typo 2024-08-06 00:20:58 +05:30
Siddharth Singh
aa0727a96d
acct can be a bare pubkey 2024-08-06 00:20:05 +05:30
Siddharth Singh
f6bd7fc3a5
fail gracefully if getHandle fails to fetch profile 2024-08-05 23:23:13 +05:30
P. Reis
0a3ed4e160 refactor(zap split): rename amount to weight 2024-08-05 14:41:16 -03:00
Siddharth Singh
c109d06a6e
better getHandle 2024-08-05 23:00:08 +05:30
P. Reis
25bbeceb8d refactor: rename zap_splits_mastodon to zapSplitEntity 2024-08-05 14:29:30 -03:00
Siddharth Singh
9a96582bfc
catch errors while building opengraph metadata to allow _some_ metadata to make it out still 2024-08-05 22:36:48 +05:30
Siddharth Singh
18e0c990e4
add ditto favicon to default metadata 2024-08-05 22:35:55 +05:30
Siddharth Singh
00fe609ef1
fix naked pubkey test regex 2024-08-05 21:36:49 +05:30
Siddharth Singh
2f9dd7e9a2
more logging 2024-08-05 21:34:20 +05:30
Siddharth Singh
a3012d341b
log stuff 2024-08-05 21:32:44 +05:30
Siddharth Singh
9175596d5f
use nip27 replacer instead of janky regex 2024-08-05 20:24:03 +05:30
Siddharth Singh
e4f24c3b26
format 2024-08-05 20:18:49 +05:30
Siddharth Singh
7c56b9dad8
use stickynotes, move storages.db to inside buildTemplateOpts 2024-08-05 20:18:16 +05:30
Siddharth Singh
85b54e81be
ignore OG metadata errors 2024-08-05 20:14:43 +05:30
Siddharth Singh
2ad81d3fbf
sort imports 2024-08-05 20:07:08 +05:30
Siddharth Singh
33da9a41b2
rewrite metadata generation 2024-08-05 20:04:26 +05:30
Siddharth Singh
5785f07052
tpl --> metadataView 2024-08-05 20:02:03 +05:30
Siddharth Singh
c7e5aed679
move parseAndVerifyNip05 to utils/nip05 2024-08-05 18:12:53 +05:30
Siddharth Singh
29d7495c39
add site property to OpenGraphTemplateOpts 2024-08-05 15:43:56 +05:30
Siddharth Singh
7e2217ccd8
use entities escape instead of shitty custom one 2024-08-05 15:42:32 +05:30
Siddharth Singh
0706f53b9f
sort imports by path 2024-08-05 15:18:17 +05:30
Siddharth Singh
c863655b4d
sort imports by path 2024-08-05 15:15:48 +05:30
Siddharth Singh
c0a6d48d55
rename OG_META_PLACEHOLDER --> META_PLACEHOLDER 2024-08-05 15:14:51 +05:30
Siddharth Singh
2cafc2014f
remove cf from lockfile 2024-08-05 15:13:09 +05:30
Alex Gleason
4c83d6d1b2
Do frontendController like I want to 2024-08-04 13:26:05 -05:00
Siddharth Singh
95ef308d0e
fix typo in nip05 cleaner regex 2024-08-04 12:25:30 +05:30
Siddharth Singh
8b8a801da8
handle underscores in nip05 correctly 2024-08-04 12:21:31 +05:30
Siddharth Singh
b95e31cd5d
rework kind 0 handling 2024-08-04 12:07:24 +05:30
Siddharth Singh
6aa49c12e1
steal html util from campfire, remove external dependency on cf 2024-08-04 11:10:33 +05:30
Siddharth Singh
77d73c47ee
move a bunch of utils to their own file 2024-08-04 11:07:29 +05:30
Siddharth Singh
435ca60b0d
update todo 2024-08-04 05:52:51 +05:30
Siddharth Singh
7aaa1bc030
generate metadata for bech32 encoded entities 2024-08-04 05:52:24 +05:30
Siddharth Singh
80f8932513
send profile pictures where possible 2024-08-04 04:54:50 +05:30
Siddharth Singh
8c9facdad7
remove unnecessary logs and use nip05s if avl 2024-08-04 04:49:24 +05:30
Siddharth Singh
baa6e318f3
remove premature optimization in serveStaticWithOG 2024-08-04 04:43:47 +05:30
Siddharth Singh
5ee0c1e852
opengraphMiddleware.ts --> serveStaticWithOG.ts 2024-08-04 04:36:36 +05:30
Siddharth Singh
b8eb549190
opengraphFrontendController --> serveStaticWithOG 2024-08-04 04:35:56 +05:30
Siddharth Singh
4e522bd90f
always use summary type for twitter 2024-08-04 03:35:04 +05:30
Siddharth Singh
2382503785
flip the orders? 2024-08-04 03:20:57 +05:30
Siddharth Singh
a530313d15
update todo 2024-08-04 03:15:04 +05:30
Siddharth Singh
7889ee5db4
first version of opengraph functionality 2024-08-04 03:06:53 +05:30
Alex Gleason
950adb25c6
Fix relay connections metrics 2024-08-03 08:19:21 -05:00
Alex Gleason
5ac1abdf69 Merge branch 'fix-documentation' into 'main'
docs/fix: rename db:import to nostr:pull

See merge request soapbox-pub/ditto!443
2024-08-03 00:35:14 +00:00
P. Reis
84c56282ac docs/fix: rename db:import to nostr:pull 2024-08-02 21:19:52 -03:00
Alex Gleason
3e6f4bb256 Merge branch 'db-export' into 'main'
Add db:export command

See merge request soapbox-pub/ditto!441
2024-08-02 22:00:15 +00:00
Alex Gleason
ba3f816955
Add db:import task 2024-08-02 16:54:35 -05:00
P. Reis
6277b8ab0f refactor: remove zap split from instance V1 endpoint 2024-08-02 18:47:59 -03:00
P. Reis
baa00e45a6 feat: create getZapSplitsController 2024-08-02 18:47:21 -03:00
Alex Gleason
3bec54ee76
Let SQLite transfer asyncIterables 2024-08-02 16:45:41 -05:00
Alex Gleason
9543049419
Add db:export command 2024-08-02 16:31:39 -05:00
Alex Gleason
44a61c4a52
Rework migrations logging 2024-08-02 16:31:06 -05:00
Alex Gleason
975294b8a4 Merge branch 'firehose-concurrency' into 'main'
Limit firehose concurrency

See merge request soapbox-pub/ditto!440
2024-08-01 17:07:08 +00:00
Alex Gleason
b05bf37cb3
Limit firehose concurrency 2024-08-01 11:51:38 -05:00
Alex Gleason
b47c53038f Merge branch 'in-any' into 'main'
Convert IN operators to = ANY() operators on Postgres

See merge request soapbox-pub/ditto!439
2024-07-31 20:08:09 +00:00
Alex Gleason
49bf38d27b
Fix kysely dependency version mismatch 2024-07-31 15:00:05 -05:00
Alex Gleason
d73370cc68
Convert IN operators to = ANY() operators on Postgres 2024-07-31 14:41:04 -05:00
Alex Gleason
7860dd2a0c Merge branch 'policy-metrics' into 'main'
Add Policy metrics

See merge request soapbox-pub/ditto!438
2024-07-30 20:56:09 +00:00
Alex Gleason
8960bdcca9
Add Policy metrics 2024-07-30 15:47:55 -05:00
Alex Gleason
9b521e9f36
metricsMiddleware: add comments 2024-07-30 14:37:28 -05:00
Alex Gleason
24d6ae0ce9
Update gleasonator policy in deno.lock 2024-07-30 14:37:15 -05:00
Alex Gleason
caaababbab
Upgrade Nostrify to v0.28.0 2024-07-30 00:01:21 -05:00
Alex Gleason
67f65b4826 Merge branch 'context' into 'main'
Improve performance of /context endpoint

See merge request soapbox-pub/ditto!437
2024-07-30 04:46:31 +00:00
Alex Gleason
a8e81e304e
context: reverse descendants 2024-07-29 23:43:04 -05:00
Alex Gleason
edc4607c8d
Improve performance of /context endpoint 2024-07-29 23:40:08 -05:00
Alex Gleason
ce18cb928a
KyselyLogger: also log errors 2024-07-29 21:19:44 -05:00
Alex Gleason
c54d801dd0 Merge branch 'tag-queries' into 'main'
Vastly improve tag query performance

Closes #169

See merge request soapbox-pub/ditto!436
2024-07-29 21:50:40 +00:00
Alex Gleason
18e446bd05
Delete zap split tests 2024-07-29 16:46:27 -05:00
Alex Gleason
a0952bc4c1
zap-split.test: use using 2024-07-29 16:42:18 -05:00
Alex Gleason
37f229408c
Seed zap splits when Storages.db is first accessed 2024-07-29 15:59:29 -05:00
Alex Gleason
31f5254fb3
Clear timeouts in tag queries migration 2024-07-29 15:37:45 -05:00
Alex Gleason
48a4e30e38
trends: read directly from the tags table instead of doing an inner join on events 2024-07-29 15:33:16 -05:00
Alex Gleason
ece18c9bd8
Add tags table migration 2024-07-29 15:32:36 -05:00
Alex Gleason
df9ae26a3a
Upgrade Nostrify to v0.27.0 2024-07-29 14:18:46 -05:00
Alex Gleason
51bdd977e1
Merge remote-tracking branch 'origin/main' into tag-queries 2024-07-29 14:14:35 -05:00
Alex Gleason
ac15aa431b Merge branch 'postgres-support-testing' into 'main'
Support tests with Postgres

Closes #171

See merge request soapbox-pub/ditto!435
2024-07-29 01:15:17 +00:00
P. Reis
a271340ffc test: use postgres in hydrate.test.ts 2024-07-26 19:01:18 -03:00
P. Reis
9c02a2d555 refactor: remove nip05 enhancement and tests 2024-07-26 18:49:31 -03:00
P. Reis
6551f0c677 Merge branch 'main' into postgres-support-testing
Update local branch to latest. This branch has the NIP-05 but it will be overriden
2024-07-26 18:32:30 -03:00
Alex Gleason
58df902a7b Merge branch 'fix-startup' into 'main'
Fix: import startup.ts file in app.ts

See merge request soapbox-pub/ditto!434
2024-07-25 19:41:47 +00:00
P. Reis
dc94d21374 fix(app.ts): import startup.ts file 2024-07-25 16:32:49 -03:00
Alex Gleason
24b950ebd2 Merge branch 'add-zap-tag' into 'main'
Add zap tag to kind 1 event

Closes #133

See merge request soapbox-pub/ditto!432
2024-07-25 18:12:57 +00:00
P. Reis
e458608e38 refactor: rename createZapSplitsIfNotExists to seedZapSplits 2024-07-25 15:10:54 -03:00
P. Reis
882f8009dc refactor: rename isNumberFrom1To100 to percentageSchema 2024-07-25 15:06:50 -03:00
P. Reis
f3d521356d refactor: get rid of isObjectEmpty function 2024-07-25 14:52:52 -03:00
P. Reis
541b5b1c39 refactor: imports in alphabetical order 2024-07-25 14:52:03 -03:00
P. Reis
f94ae7606c refactor: change zapSplitSchema to z.record()) 2024-07-25 11:11:44 -03:00
Alex Gleason
75e9837c09
Upgrade Nostrify to v0.27.0-rc.4 2024-07-24 13:59:21 -05:00
P. Reis
85806f7ea8 refactor: use object fields instead of tuple in zapSplitSchema 2024-07-24 11:14:42 -03:00
P. Reis
961da0f52c refactor: change error message in updateZapSplitsController & deleteZapSplitsController 2024-07-24 10:56:12 -03:00
P. Reis
ddd1972c83 refactor(app.ts): move cron function and startFirehose function to startup.ts 2024-07-24 10:55:30 -03:00
P. Reis
23bb24929c refactor: remove zap split creation from instanceV1Controller endpoint 2024-07-24 10:54:56 -03:00
P. Reis
1698c1b19b feat: create startup file 2024-07-24 10:54:20 -03:00
P. Reis
86874e3a08 feat: create createZapSplitsIfNotExists() function 2024-07-24 10:53:32 -03:00
Alex Gleason
2b8009d840
trends: catch initial queries 2024-07-23 23:07:34 -05:00
Alex Gleason
7949c95f77
try-catch trending tags cron 2024-07-23 22:32:16 -05:00
Alex Gleason
5ebde99320
trends: Deno.cron try/catch 2024-07-23 22:19:53 -05:00
Alex Gleason
64eeee5ff7
Upgrade Nostrify to v0.27.0-rc.3 2024-07-23 22:09:51 -05:00
P. Reis
0e43d1e8a7 refactor: add zap tag with new data structure 2024-07-23 22:40:38 -03:00
P. Reis
c49460e37d refactor(instance.ts): use new zap_split data structure in ditto hard coded pubkey 2024-07-23 20:41:02 -03:00
P. Reis
75ad25ccac test(zap-split): update to be in accord with new data structure 2024-07-23 20:39:51 -03:00
P. Reis
2ebaee8807 refactor: change DittoZapSplits data structure to use object fields instead of array 2024-07-23 20:39:23 -03:00
P. Reis
7cdfb67b99 refactor: rename officialDittoAccountPubkey to dittoPubkey & officialDittoAccountMsg to dittoMsg 2024-07-23 20:25:02 -03:00
P. Reis
a0c952b9b9 refactor: do not use isObjectEmpty function in if condition, zap tag 2024-07-23 20:15:44 -03:00
P. Reis
de32930c44 refactor: use exclamation mark (bang) instead of 'as string' cast 2024-07-23 18:26:06 -03:00
P. Reis
80e14c65c0 refactor: rename zap_split.ts to zap-split.ts, rename tests as well 2024-07-23 18:14:22 -03:00
Alex Gleason
ff35357121
Upgrade Nostrify to v0.27.0-rc.2 2024-07-23 15:13:02 -05:00
Alex Gleason
e400641757
Improve performance of tag queries 2024-07-23 10:29:45 -05:00
P. Reis
5a5e8b7c5d feat(createStatusController): add 'zap' tag to event 2024-07-21 20:11:26 -03:00
P. Reis
449a3497ba feat: create deleteZapSplitsController 2024-07-21 19:40:55 -03:00
P. Reis
2e66af26db feat: create updateZapSplitsController 2024-07-21 19:26:05 -03:00
P. Reis
2fe9b9f98d feat: get zap splits and return it in api/v1/instance endpoint 2024-07-21 19:22:53 -03:00
Alex Gleason
98dfd8f4b8 Merge branch 'update-postgres-js' into 'main'
update pinned version of postgres.js

See merge request soapbox-pub/ditto!430
2024-07-20 22:04:27 +00:00
Siddharth Singh
2acfcb3951
update lock file 2024-07-21 03:23:15 +05:30
Siddharth Singh
b3dba0f793
update pinned version of postgres.js 2024-07-21 03:19:05 +05:30
Alex Gleason
4304715c1e
pool: skip event verification 2024-07-20 13:38:56 -05:00
Alex Gleason
9cb85e42d2 Merge branch 'use-npool-nostrify' into 'main'
Replace PoolStore with NPool & add tests for outbox.ts file and RelayError.ts file

Closes #148, #180, and #181

See merge request soapbox-pub/ditto!424
2024-07-20 18:33:32 +00:00
Alex Gleason
8768bb1bad
Merge remote-tracking branch 'origin/main' into use-npool-nostrify 2024-07-20 13:31:05 -05:00
P. Reis
1f9896bdbf test: getZapSplits function return empty object 2024-07-19 19:30:31 -03:00
P. Reis
09eb444c9b test: update so getZapSplits function returns undefined 2024-07-19 19:19:35 -03:00
P. Reis
beee0e76e7 refactor: allow to return undefined in getZapSplits function 2024-07-19 19:19:04 -03:00
P. Reis
3bc3e7675d test: getZapSplits function 2024-07-19 17:36:12 -03:00
P. Reis
76a591ab6d feat: create getZapSplits function 2024-07-19 17:20:31 -03:00
P. Reis
0c9e3e2b47 test(utils.ts): isObjectEmpty function 2024-07-19 16:27:10 -03:00
P. Reis
c17db58448 feat(utils.ts): create isObjectEmpty function 2024-07-19 16:26:50 -03:00
P. Reis
cc6441d239 refactor(utils.ts): remove unused imports 2024-07-19 15:22:35 -03:00
P. Reis
c2225da8dd test(utls.ts): add more cases, isNumberFrom1To100 function 2024-07-19 13:34:45 -03:00
P. Reis
11809637ee test(utils.ts): isNumberFrom1To100 function 2024-07-19 13:21:17 -03:00
P. Reis
dcec2ecdd0 feat: create isNumberFrom1To100 function 2024-07-19 13:19:04 -03:00
Alex Gleason
8c19c5ba09 Merge branch 'stable-sort' into 'main'
Sort events by id after created_at

See merge request soapbox-pub/ditto!429
2024-07-19 03:49:06 +00:00
Alex Gleason
8ec5feae13
Sort events by id after created_at 2024-07-18 22:48:11 -05:00
Alex Gleason
13f0d3f49e
Upgrade Nostrify to v0.26.2 2024-07-18 22:01:16 -05:00
Alex Gleason
7793db3e2c
Upgrade Nostrify to v0.26.1 2024-07-17 23:13:04 -05:00
Alex Gleason
b18d326f5d Merge branch 'revert-bf9b816e' into 'main'
Revert "Merge branch 'tag-perf' into 'main'"

See merge request soapbox-pub/ditto!426
2024-07-18 04:11:50 +00:00
Alex Gleason
2d239fcaec Revert "Merge branch 'tag-perf' into 'main'"
This reverts merge request !425
2024-07-18 04:11:04 +00:00
Alex Gleason
bf9b816e0b Merge branch 'tag-perf' into 'main'
EventsDB: query tags by converting to ids filter

See merge request soapbox-pub/ditto!425
2024-07-18 03:33:03 +00:00
Alex Gleason
ff8d7ef9d4
EventsDB: normalizeFilters before expanding tag queries 2024-07-17 20:11:31 -05:00
Alex Gleason
0f5c28deeb
EventsDB: query tags by converting to ids filter 2024-07-17 19:58:12 -05:00
P. Reis
31e5b89750 refactor: delete pool-store.ts file 2024-07-17 11:42:27 -03:00
P. Reis
bccf33f80a feat(storages): remove PoolStore, use NPool 2024-07-17 11:42:27 -03:00
P. Reis
e01e0049e3 fix: purify event before publishing to other relays 2024-07-17 11:40:08 -03:00
P. Reis
f4f0c5fb86 fix(storages): publish to write relays only as well 2024-07-17 11:00:49 -03:00
P. Reis
f5ee5ea6a3 test(RelayError): code coverage 100.00% 2024-07-17 10:53:31 -03:00
P. Reis
85a6089e36 test(outbox): coverage 100% 2024-07-17 10:39:50 -03:00
P. Reis
4d4273832a fixture: add kind 10002 2024-07-17 10:39:50 -03:00
P. Reis
cc51917d61 fix(outbox): remove comment, use author pubkey 2024-07-17 10:39:50 -03:00
Alex Gleason
eebc3e5c61 Merge branch 'update-dependencies' into 'main'
chore: update dependencies

See merge request soapbox-pub/ditto!423
2024-07-16 19:29:23 +00:00
P. Reis
aec2cd3b9f chore: update dependencies 2024-07-16 16:26:22 -03:00
P. Reis
842b527273 test: update to use kysely-postgres-js 2024-07-16 14:47:14 -03:00
P. Reis
8afc3bca3d refactor: order of imports 2024-07-16 14:06:32 -03:00
P. Reis
cf4ee051db Merge branch 'main' into search-nip05-enhance-and-postgres-support-testing 2024-07-16 13:58:47 -03:00
Alex Gleason
d32cccd70e Merge branch 'coverage-support' into 'main'
ci: add code coverage

See merge request soapbox-pub/ditto!421
2024-07-16 16:19:08 +00:00
Alex Gleason
00f09e1846 Merge branch 'use-postgres-js' into 'main'
replace kysely_deno_postgres with kysely-postgres-js

See merge request soapbox-pub/ditto!404
2024-07-16 14:27:46 +00:00
Alex Gleason
c2f578a2bb
DittoPostgres: handle pool not being opened yet 2024-07-16 09:26:49 -05:00
Alex Gleason
e208d7ef56
Merge remote-tracking branch 'origin/main' into use-postgres-js 2024-07-15 21:35:29 -05:00
Siddharth Singh
3aa8266bbe
use idle count to get avl connections 2024-07-16 07:44:55 +05:30
Siddharth Singh
53343ba349
messing with conn stats 2024-07-16 07:44:39 +05:30
P. Reis
b45eab64b5 ci: add code coverage 2024-07-15 19:05:28 -03:00
Alex Gleason
6fe034d55a
Bump version to v1.1.0 2024-07-15 08:11:25 -05:00
Siddharth Singh
404306f203
change to connection-stats branch 2024-07-15 14:23:23 +05:30
Alex Gleason
c2026a340a
Update CHANGELOG 2024-07-14 15:59:02 -05:00
Alex Gleason
4fa5517c58 Merge branch 'tweak-timeouts' into 'main'
Increase default database timeouts

See merge request soapbox-pub/ditto!420
2024-07-14 15:11:43 +00:00
Alex Gleason
a49e56f2a0
Increase default database timeouts 2024-07-14 10:10:26 -05:00
Alex Gleason
aac6505bf5 Merge branch 'deno-v1.45.2' into 'main'
Upgrade Deno to v1.45.2

See merge request soapbox-pub/ditto!419
2024-07-13 20:51:30 +00:00
Alex Gleason
46c3e52b98
Upgrade Deno to v1.45.2 2024-07-13 15:49:19 -05:00
Alex Gleason
39fdbc1acb
Delete scavenger.test.ts 2024-07-12 14:01:21 -05:00
Alex Gleason
d6b49b169d Merge branch 'timeouts-conf' into 'main'
Make database timeouts configurable

See merge request soapbox-pub/ditto!417
2024-07-12 18:53:07 +00:00
Alex Gleason
96fe8920cd
Make database timeouts configurable 2024-07-12 13:49:44 -05:00
Alex Gleason
c2b13b1a63
Add a ts-ignore instead of as any 2024-07-11 17:22:12 -05:00
Alex Gleason
cd961dad86
delay -> sleep, style tweaks 2024-07-11 17:19:47 -05:00
Alex Gleason
9584638d5c
Merge remote-tracking branch 'origin/main' into use-postgres-js 2024-07-11 17:16:11 -05:00
Alex Gleason
d0d385682d Merge branch 'ws-limit' into 'main'
Rate-limit websocket endpoints

See merge request soapbox-pub/ditto!415
2024-07-11 22:11:56 +00:00
Alex Gleason
5c6479b3fe
Rate-limit messages to the relay 2024-07-11 17:10:05 -05:00
Alex Gleason
92061c267e
Merge remote-tracking branch 'origin/main' into ws-limit 2024-07-11 17:02:00 -05:00
Alex Gleason
c4b35d11c8 Merge branch 'deno-v1.45.0' into 'main'
Upgrade Deno to v1.45.0

See merge request soapbox-pub/ditto!414
2024-07-11 21:56:48 +00:00
Alex Gleason
6245200e21
Upgrade Deno to v1.45.0 2024-07-11 16:55:02 -05:00
Alex Gleason
b3067e64ee Merge branch 'e-tags' into 'main'
createStatusController: add relay hints

See merge request soapbox-pub/ditto!413
2024-07-06 23:25:41 +00:00
Alex Gleason
fa53dd7f8d
createStatusController: add relay hints
Fixes https://github.com/nostrability/nostrability/issues/52
2024-07-07 00:23:00 +01:00
Alex Gleason
ed067e541e Merge branch 'improve-errors' into 'main'
Improve signer timeout errors

See merge request soapbox-pub/ditto!412
2024-07-06 22:03:54 +00:00
Alex Gleason
842adfd72b
Improve signer timeout errors 2024-07-06 23:01:00 +01:00
Alex Gleason
155ca77074 Merge branch 'fix-not-being-able-to-post' into 'main'
Fix not being able to post

Closes #175

See merge request soapbox-pub/ditto!411
2024-07-06 19:52:33 +00:00
Alex Gleason
2167106577
Fix not being able to post 2024-07-06 20:50:39 +01:00
Siddharth Singh
36b9aae1ab
switch to postgres.js available-connections branch temporarily 2024-07-06 20:07:02 +05:30
P. Reis
71bdfea317 refactor: get database dialect from Conf.db.dialect 2024-07-06 11:11:41 -03:00
Siddharth Singh
102398967e
fix type stuff 2024-07-06 18:18:38 +05:30
Siddharth Singh
3495092eff
add poolsize and availableconnections metrics back 2024-07-06 18:15:21 +05:30
Siddharth Singh
a804608afb Merge branch 'main' into 'use-postgres-js'
# Conflicts:
#   deno.json
#   src/db/adapters/DittoPostgres.ts
2024-07-06 12:03:21 +00:00
P. Reis
5412d2a07b fix(EventsDB): also add a split only by '@' at symbol 2024-07-05 20:43:13 -03:00
P. Reis
92231dc452 test: query by NIP-05 2024-07-05 20:42:11 -03:00
P. Reis
01966496c1 feat: print which dialect is being used when calling createTestDB 2024-07-05 18:49:37 -03:00
P. Reis
13d346afbd refactor: remove console.log 2024-07-05 18:43:14 -03:00
P. Reis
1b3082cd22 build: set ALLOW_TO_USE_DATABASE_URL in postgres ci 2024-07-05 18:34:28 -03:00
P. Reis
fed0c70f69 feat: only run tests with Postgres if ALLOW_TO_USE_DATABASE_URL is set to true 2024-07-05 18:33:29 -03:00
P. Reis
7e965f4ade refactor(test.ts): explain why set DATABASE_URL to sqlite://:memory: 2024-07-05 17:59:12 -03:00
P. Reis
1af229da45 build(gitlab-ci): use deno task test in postgres ci 2024-07-05 17:52:13 -03:00
P. Reis
34bbf6e39a test(pipeline): refactor to use createTestDB instead of getTestDB 2024-07-05 17:48:34 -03:00
P. Reis
f380120cd3 test: refactor to use createTestDB instead of getTestDB 2024-07-05 17:48:06 -03:00
P. Reis
d18796956b test(hydrate): refactor to only use sqlite 2024-07-05 17:43:47 -03:00
P. Reis
85fd7909e6 feat: add optional kysely in HydrateOpts interface 2024-07-05 17:42:19 -03:00
P. Reis
8e1826020c test(EventsDB): remove createDB function 2024-07-05 17:35:25 -03:00
P. Reis
2154cf011b test: create createTestDB function, supports both Sqlite and Postgres 2024-07-05 17:26:27 -03:00
P. Reis
12b2032d87 refactor(EventsDB.test): add one blank line between functions 2024-07-04 22:50:12 -03:00
P. Reis
a9f79176a2 test: support sqlite and postgres 2024-07-04 22:43:56 -03:00
Alex Gleason
a9afe03a37 Merge branch 'metrics-resp' into 'main'
HTTP Response metrics

See merge request soapbox-pub/ditto!410
2024-07-04 23:11:12 +00:00
Alex Gleason
96a8ccb2e6
HTTP Response metrics 2024-07-05 00:07:59 +01:00
Alex Gleason
d4713cae01
Move errorHandler to a separate file 2024-07-04 23:53:20 +01:00
Alex Gleason
8923a5ee55 Merge branch 'eventsdb-no-ephemeral' into 'main'
EventsDB: remove queries for ephemeral kinds

See merge request soapbox-pub/ditto!409
2024-07-04 22:40:17 +00:00
Alex Gleason
193dd1a011
EventsDB: remove queries for ephemeral kinds 2024-07-04 23:38:16 +01:00
P. Reis
cbb48867c1 test: attempt to use Postgres 2024-07-04 18:13:31 -03:00
P. Reis
d8247dc76a build: remove DATABASE_URL in test script 2024-07-04 18:08:03 -03:00
P. Reis
78d41bbd6d feat(EventsDB): add nip05 split in buildUserSearchContent() 2024-07-03 20:41:48 -03:00
Alex Gleason
5addf58a10 Merge branch 'handle-timeout-error' into 'main'
Handle timeout error in Hono app.onError() function & send custom error messages in /relay

See merge request soapbox-pub/ditto!407
2024-07-02 21:45:12 +00:00
P. Reis
ba29035413 refactor: put conditional into just one line 2024-07-02 18:43:28 -03:00
P. Reis
d3c3ecfd35 test(EventsDB): refactor to use RelayError instead of Error 2024-07-02 18:40:21 -03:00
P. Reis
e169749b82 refactor(EventsDB): throw RelayError instead of Error 2024-07-02 18:39:55 -03:00
P. Reis
2d017e8102 refactor(relay): remove invalid filter condition 2024-07-02 18:39:22 -03:00
P. Reis
a868512188 refactor: error messages in app.onError() 2024-07-02 18:38:16 -03:00
P. Reis
1731e7dac9 Merge branch 'main' into handle-timeout-error
(((updating local branch)))
2024-07-02 17:31:36 -03:00
P. Reis
360efe089d test(EventsDB): throw error for large since, until and kinds filter 2024-07-02 17:31:12 -03:00
P. Reis
cac5c9c1e0 refactor: change timeout error message 2024-07-02 17:17:29 -03:00
P. Reis
e6c38550c6 feat: add onError() function hono handler 2024-07-02 17:15:47 -03:00
P. Reis
a7f2fb06ee feat(relay): send custom error messages - since, until & kind 2024-07-02 17:09:17 -03:00
Alex Gleason
3e7bab538a
Increase timeout for account statuses endpoint and feed endpoints 2024-07-02 20:13:44 +01:00
Alex Gleason
c7092f5d2d
Increase query timeout of feeds 2024-07-02 09:22:59 +01:00
Alex Gleason
fd769c125c Merge branch 'zapped-by-pagination-sort-amount' into 'main'
zapped_by: add pagination & sort amount

Closes #159

See merge request soapbox-pub/ditto!394
2024-07-02 05:17:11 +00:00
Alex Gleason
4c257fa529 Merge branch 'timeouts' into 'main'
Add query timeouts

See merge request soapbox-pub/ditto!403
2024-07-02 05:16:09 +00:00
Alex Gleason
137e2eae52 Merge branch 'nostr-pull-improvements' into 'main'
improvements to nostr:pull script

See merge request soapbox-pub/ditto!406
2024-07-02 03:19:21 +00:00
Siddharth Singh
757e5c9baa
print name as import acknowledgement 2024-07-02 05:21:16 +05:30
Siddharth Singh
d2df6721bd
fix kind 1 querying logic 2024-07-02 05:01:16 +05:30
Siddharth Singh
f1e9eb4f4c
fetch each author's notes separately 2024-07-02 04:58:06 +05:30
Siddharth Singh
5f0b1ffe79
fetch profiles separately from notes 2024-07-02 04:56:38 +05:30
Alex Gleason
ae687bb525
Increase timeouts 2024-07-01 23:05:03 +01:00
Alex Gleason
3ae6d39ebc
Increase notifications endpoint timeout 2024-07-01 20:29:06 +01:00
Alex Gleason
4e150edb5b
Actually enable query timeouts 🤦 2024-07-01 19:48:28 +01:00
Alex Gleason
a00db2f4c1 Merge branch 'script-import-user' into 'main'
deno task db:import

See merge request soapbox-pub/ditto!405
2024-07-01 17:54:18 +00:00
Siddharth Singh
6974b78952
db:import --> nostr:pull 2024-07-01 23:21:29 +05:30
Siddharth Singh
e07be77de7
fix import order 2024-07-01 23:13:20 +05:30
Siddharth Singh
98e9ccfc46
fix import 2024-07-01 23:08:15 +05:30
Siddharth Singh
434056b839
rename evt to event 2024-07-01 23:06:41 +05:30
Siddharth Singh
ea987dfa14
support raw pubkeys as well as npubs 2024-07-01 23:06:09 +05:30
Siddharth Singh
65f77e845d
fmt 2024-07-01 21:43:01 +05:30
Siddharth Singh
98aaab8e51
switch to deno.land/postgresjs for free 4x speed increase 2024-07-01 21:42:50 +05:30
Alex Gleason
092a20088a
Reduce timeouts 2024-07-01 09:18:42 +01:00
Alex Gleason
c3ffe7c7f7
EventsDB: fix limit being passed to NDatabase 2024-07-01 08:53:03 +01:00
Alex Gleason
d062f6bbb6
Try lazy pool initialization 2024-07-01 08:44:01 +01:00
Alex Gleason
96fe171d65
Use kysely_deno_postgres with simple transactions 2024-07-01 07:22:33 +01:00
Siddharth Singh
480f4ed370
fmt 2024-06-30 16:31:02 +05:30
Siddharth Singh
9f3f6917d3
import script works now 2024-06-30 15:50:25 +05:30
Siddharth Singh
80f6172a64
create first version of import script 2024-06-30 15:35:46 +05:30
Siddharth Singh
ae140933f5
replace kysely_deno_postgres with kysely-postgres-js 2024-06-30 13:13:01 +05:30
Alex Gleason
9ea6c7b00b
Add query timeouts 2024-06-29 22:26:51 +01:00
Alex Gleason
bdd3b2224e Merge branch 'ms-to-seconds-histogram' into 'main'
fix(dbQueryTimeHistogram): change name to milliseconds ms instead of seconds

See merge request soapbox-pub/ditto!401
2024-06-27 17:40:32 +00:00
P. Reis
7f7efd12b8 fix(dbQueryTimeHistogram): change name to milliseconds ms instead of seconds 2024-06-27 13:32:23 -03:00
Alex Gleason
eba0605e32 Merge branch 'db-query-time-prom-metric' into 'main'
basic (and incredibly stupid but potentially genius) db_query_time histogram

See merge request soapbox-pub/ditto!400
2024-06-27 13:53:17 +00:00
P. Reis
9cdb8ec534 fix(KyselyLogger): use dbQueryTimeHistogram.observe 2024-06-27 10:34:12 -03:00
P. Reis
a81bc57961 refactor(dbQueryTimeHistogram): get rid of labelNames and buckets 2024-06-27 10:32:07 -03:00
P. Reis
ac9bdfde62 refactor(KyselyLogger): use startTimer instead of observe 2024-06-27 10:23:10 -03:00
P. Reis
d580cac763 refactor: dbQueryTimeHistogram 2024-06-27 10:20:55 -03:00
P. Reis
0f392b2dba fix(relays): get rid of custom kind 13314 conditional 2024-06-27 10:12:44 -03:00
Siddharth Singh
3e40e690c5
check admin pubkey while changing threshold 2024-06-26 01:44:44 +05:30
Siddharth Singh
ab5f451929
fmt 2024-06-26 01:33:02 +05:30
Siddharth Singh
7c7c584b78
basic (and incredibly stupid but potentially genius) db_query_time histogram 2024-06-26 01:30:16 +05:30
Alex Gleason
a965c3c997 Merge branch 'pg-metrics' into 'main'
Collect database connections metrics

See merge request soapbox-pub/ditto!399
2024-06-25 03:14:26 +00:00
Alex Gleason
d7d14194d7
Collect database connections metrics 2024-06-24 22:01:01 -05:00
Alex Gleason
7ecfcd84b3
Actually use metricsMiddleware, whoops 2024-06-24 15:49:27 -05:00
P. Reis
797c866830 refactor: storeEvent does not return event, move kysely into a variable above 2024-06-24 12:07:33 -03:00
Alex Gleason
5889dfbf71 Merge branch 'prom-ws-conn' into 'main'
prometheus: add gauges for websocket connections

See merge request soapbox-pub/ditto!398
2024-06-24 14:25:26 +00:00
Alex Gleason
e6cd3d9e47
prometheus: add gauges for websocket connections 2024-06-24 09:23:26 -05:00
Alex Gleason
4ed289e5c3 Merge branch 'prom-relay-verb' into 'main'
prometheus: track relay messages by verb

Closes #166

See merge request soapbox-pub/ditto!397
2024-06-24 13:20:48 +00:00
Alex Gleason
e0b1029953
prometheus: track relay messages by verb 2024-06-24 08:18:11 -05:00
P. Reis
fdb720386d fix(handleZaps): reject all kinds but 9735 2024-06-23 23:51:10 -03:00
P. Reis
e1ee3bd8e9 refactor: remove scavenger, put logic directly into pipeline 2024-06-23 23:45:32 -03:00
P. Reis
05bf417bcc perf(event_zaps): make two separate indexes instead of a compound index 2024-06-23 22:49:15 -03:00
P. Reis
3a8ade4de2 Merge branch 'main' into zapped-by-pagination-sort-amount 2024-06-23 18:49:56 -03:00
Alex Gleason
961cb070f0 Merge branch 'nostr-external-viewers' into 'main'
Add ditto.external property to accounts and statuses

Closes soapbox#1673

See merge request soapbox-pub/ditto!396
2024-06-23 21:11:54 +00:00
Siddharth Singh
3f7687d59f
make changes according to 24-06-24 review 2024-06-24 02:34:49 +05:30
Siddharth Singh
f19afa449a
add the ditto.external field to statuses and accounts 2024-06-24 02:03:31 +05:30
Siddharth Singh
60b4ea4643
add config values for external nostr viewer back to source code 2024-06-24 02:02:58 +05:30
Alex Gleason
39fb1eee5f
Import Sentry into workers 2024-06-23 11:59:08 -05:00
P. Reis
0d7ef68353 feat: add pagination and sort by amount - zapped_by endpoint 2024-06-23 13:38:40 -03:00
Alex Gleason
a1810219f1
Update deno.lock 2024-06-23 10:38:55 -05:00
Alex Gleason
c44347e9d1
Fix relay metrics 2024-06-22 10:28:42 -05:00
Alex Gleason
e50ba819b9
metrics: remove path from fetch and request metrics 2024-06-22 09:08:32 -05:00
Alex Gleason
ea15f291b0 Merge branch 'metrics' into 'main'
Add Prometheus metrics

See merge request soapbox-pub/ditto!395
2024-06-22 03:49:07 +00:00
Alex Gleason
88df19494a
Expose /metrics in hono 2024-06-21 22:46:37 -05:00
Alex Gleason
31a5533fd7
Add Prometheus metrics 2024-06-21 22:38:25 -05:00
P. Reis
9731fc2572 feat: add scavenger to the pipeline 2024-06-21 22:25:34 -03:00
P. Reis
89b56539d1 test(scavenger): code coverage 100.00% 2024-06-21 22:23:34 -03:00
P. Reis
771d7f79db refactor(scavenger): put SQL insert into try-catch block 2024-06-21 21:45:55 -03:00
P. Reis
1b30f10a9f test(scavenger): store valid data into event_zaps table 2024-06-21 21:39:18 -03:00
P. Reis
2c08b9a2f0 feat: create scavenger and handle kind 9735 2024-06-21 20:36:59 -03:00
P. Reis
ec82e14410 fix: add amount_millisats in event_zaps index 2024-06-21 18:35:26 -03:00
P. Reis
2d937a7378 refactor(event_zaps): rename amount to amount_millisats 2024-06-21 18:20:10 -03:00
Alex Gleason
53e7e856c1
streamingController: bail early if limited 2024-06-20 16:20:18 -05:00
Alex Gleason
44dfd15502
streamingController: rate-limit with ttl-cache 2024-06-20 16:15:31 -05:00
P. Reis
1b4ebaccd8 refactor: resolve import specifier via the active import map 2024-06-20 15:26:08 -03:00
P. Reis
bac0b48801 feat: add migration for event_zaps;create idx_event_zaps_id_amount 2024-06-20 14:36:19 -03:00
P. Reis
ddb93af09f feat(DittoTables): create EventZapRow 2024-06-20 14:33:25 -03:00
Alex Gleason
766290bd45 accountStatusesController: fix oopsie whoopsie TypeError (gj TypeScript) 2024-06-20 05:59:41 +00:00
Alex Gleason
6bdd29922a Merge branch 'disabled-no-status' into 'main'
Don't display posts of disabled user on their profile

Closes #162

See merge request soapbox-pub/ditto!393
2024-06-19 20:01:07 +00:00
Alex Gleason
003d60c959
Don't display posts of disabled user on their profile 2024-06-19 14:06:02 -05:00
Alex Gleason
8bd67720d6 Merge branch 'custom-emoji-react' into 'main'
Render custom emoji reaction in notifications

See merge request soapbox-pub/ditto!392
2024-06-19 18:38:04 +00:00
Alex Gleason
3daac37e08
Render custom emoji reaction in notifications 2024-06-19 13:35:43 -05:00
Alex Gleason
875eee7a77
Avoid using the user's own relay list when publishing events
Sadly I think these relays are causing Ditto to lock up and stop working. This sucks
2024-06-19 13:25:06 -05:00
Alex Gleason
6ee9eb63d3
Get Ditto version from deno.json 2024-06-18 18:05:11 -05:00
Alex Gleason
335cb991d2
Add a few NIP-011 limitation fields 2024-06-18 17:49:52 -05:00
Alex Gleason
5ac19715cd Merge branch 'limiter' into 'main'
Rate-limit HTTP requests

See merge request soapbox-pub/ditto!390
2024-06-18 20:47:22 +00:00
Alex Gleason
0d3c619245
rateLimitMiddleware: improve tsdoc comment 2024-06-18 15:24:44 -05:00
Alex Gleason
330b38ff68
Move rateLimiterMiddleware to a separate file 2024-06-18 14:28:13 -05:00
Alex Gleason
72f5391f97
Update deno.lock 2024-06-18 13:38:56 -05:00
Alex Gleason
03fc6e777c
nginx: add more proxy headers 2024-06-18 13:38:17 -05:00
Alex Gleason
a824d72a1a
Add IP rate limiter 2024-06-18 12:09:29 -05:00
Alex Gleason
5ba0c8c14a Merge branch 'hono-jsr' into 'main'
Upgrade hono, switch it to use JSR

See merge request soapbox-pub/ditto!389
2024-06-18 16:53:42 +00:00
Alex Gleason
66abfa38c3
Upgrade hono, switch it to use JSR 2024-06-18 11:51:51 -05:00
Alex Gleason
f56aa26996 Merge branch 'uuid-trx' into 'main'
Upgrade kysely_deno_postgres

See merge request soapbox-pub/ditto!388
2024-06-18 04:40:31 +00:00
Alex Gleason
1fe4b4bb81
Upgrade kysely_deno_postgres 2024-06-17 23:36:50 -05:00
Alex Gleason
1294dcaa4e Merge branch 'revert-f81fcf0e' into 'main'
Revert "Merge branch 'stats-transaction' into 'main'"

See merge request soapbox-pub/ditto!387
2024-06-18 01:12:48 +00:00
Alex Gleason
c48b976d04 Revert "Merge branch 'stats-transaction' into 'main'"
This reverts merge request !386
2024-06-18 01:11:03 +00:00
Alex Gleason
1209b1c430 Merge branch 'fix-zap-amount-zero' into 'main'
Get zap amount from zap receipt if not present in zap request

See merge request soapbox-pub/ditto!385
2024-06-18 00:16:09 +00:00
P. Reis
8b67a05792 refactor: parse zap request with zod 2024-06-17 21:07:27 -03:00
P. Reis
bf017195a6 refactor: sort imports alphabetically 2024-06-17 20:15:51 -03:00
P. Reis
98565efa12 refactor(bolt11): get amount with new library 2024-06-17 19:49:18 -03:00
P. Reis
b237432312 fix: change bolt11 dependency to light-bolt11-decoder 2024-06-17 19:40:47 -03:00
Alex Gleason
2f3b656af5
Upgrade Nostrify to v0.23.3, remove normalizeFilters call in EventsDB (NDatabase does this now) 2024-06-17 17:29:01 -05:00
Alex Gleason
f81fcf0eec Merge branch 'stats-transaction' into 'main'
Update stats in a transaction

Closes #161

See merge request soapbox-pub/ditto!386
2024-06-17 21:42:54 +00:00
Alex Gleason
74944dcd2a
EventsDB: remove no longer relevant tests 2024-06-17 16:40:06 -05:00
Alex Gleason
8c3e16fd41
Ignore repetitive error message 2024-06-17 16:29:52 -05:00
P. Reis
c6425ad7ff fix(bolt11): print error 2024-06-17 18:15:42 -03:00
Alex Gleason
96af3bb8bf
Update stats in a transaction 2024-06-17 16:07:03 -05:00
P. Reis
7a29c349e8 fix: get amount from zap receipt if not present in zap request 2024-06-17 14:51:12 -03:00
P. Reis
2f49e94e4c test(bolt11): getAmount function 2024-06-17 14:51:12 -03:00
P. Reis
82bf36f064 feat(bolt11): create getAmount function 2024-06-17 14:51:09 -03:00
P. Reis
d33ecdc0f6 build: specify bolt11 version 2024-06-17 14:28:26 -03:00
P. Reis
d71eb47212 build(deno.lock): bolt11 dependencies 2024-06-17 11:18:59 -03:00
P. Reis
ba9a578ec0 feat: add bolt11 dependency 2024-06-17 11:05:14 -03:00
Alex Gleason
1983171193
setup: removed unused node:url import 2024-06-16 00:15:10 -05:00
Alex Gleason
dbacb6b63a
setup: handle DATABASE_URL more transparently on re-runs 2024-06-16 00:14:43 -05:00
Alex Gleason
078c267bb8 Merge branch 'config-cleanup' into 'main'
Improve the setup script and clean up config

Closes #156

See merge request soapbox-pub/ditto!384
2024-06-16 04:53:51 +00:00
Alex Gleason
c3af8299f1
Spread s3 config
Fixes https://gitlab.com/soapbox-pub/ditto/-/issues/156
2024-06-15 23:51:50 -05:00
Alex Gleason
c39fd2daa2
Improve the setup script and clean up config 2024-06-15 23:41:19 -05:00
Alex Gleason
287c89b9fd Merge branch 'entity-types' into 'main'
Add interfaces for Mastodon entity types, hide deactivated accounts

See merge request soapbox-pub/ditto!383
2024-06-16 00:38:40 +00:00
Alex Gleason
e63ee9b5a3
Add interfaces for Mastodon entity types, hide deactivated accounts 2024-06-15 19:36:34 -05:00
Alex Gleason
06db5d2b1d Merge branch 'trends-serial' into 'main'
trends: rewrite getTrendingTags to process the history in serial, split across several queries

See merge request soapbox-pub/ditto!382
2024-06-15 23:35:20 +00:00
Alex Gleason
6ce8aae0d1
trends: rewrite getTrendingTags to process the history in serial, split across several queries 2024-06-15 18:14:38 -05:00
Alex Gleason
1afd8a739a
Update deno.lock 2024-06-15 17:20:39 -05:00
Alex Gleason
a3b7acd1c1
Cache trends API results at a different interval than trends calculations 2024-06-15 17:18:55 -05:00
Alex Gleason
844ebe0323 Merge branch 'trends-script' into 'main'
Add a script to update trends

See merge request soapbox-pub/ditto!380
2024-06-15 17:19:07 +00:00
Alex Gleason
8d8e46eae8
Add a script to update trends 2024-06-15 12:13:35 -05:00
Alex Gleason
72ca7af7f0
admin-role script: minor tweaks 2024-06-15 11:40:03 -05:00
Alex Gleason
97951d5d91 Merge branch 'admin-role-script-support-npub' into 'main'
support npubs in admin:role script

See merge request soapbox-pub/ditto!366
2024-06-14 21:24:00 +00:00
Siddharth Singh
cc14f2a549
fix accidental vscode changes 2024-06-14 21:02:40 +05:30
Alex Gleason
e3f86e1b54
README: remove WIP comment
Although it is, we don't need to warn people about that anymore
2024-06-14 08:34:54 -05:00
Alex Gleason
3b6ebc651b
README: check all the boxes 2024-06-14 08:34:10 -05:00
Siddharth Singh
2380234deb
fmt 2024-06-08 00:30:22 +05:30
Siddharth Singh
2c649e0fa6
support npubs in admin:role script 2024-06-08 00:26:36 +05:30
511 changed files with 29758 additions and 9472 deletions

1
.gitignore vendored
View file

@ -1,4 +1,5 @@
.env .env
.env.*
*.cpuprofile *.cpuprofile
*.swp *.swp
deno-test.xml deno-test.xml

View file

@ -1,4 +1,4 @@
image: denoland/deno:1.44.2 image: denoland/deno:2.2.2
default: default:
interruptible: true interruptible: true
@ -6,36 +6,26 @@ default:
stages: stages:
- test - test
fmt:
stage: test
script: deno fmt --check
lint:
stage: test
script: deno lint
check:
stage: test
script: deno task check
test: test:
stage: test stage: test
script: deno task test timeout: 2 minutes
variables: script:
DITTO_NSEC: nsec1zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs4rm7hz - deno fmt --check
artifacts: - deno task lint
when: always - deno task check
paths: - deno task test --ignore=packages/transcode --coverage=cov_profile
- deno-test.xml - deno coverage cov_profile
reports: coverage: /All files[^\|]*\|[^\|]*\s+([\d\.]+)/
junit: deno-test.xml
postgres:
stage: test
script: deno task db:migrate
services: services:
- postgres:16 - postgres:16
variables: variables:
DITTO_NSEC: nsec1zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs4rm7hz DITTO_NSEC: nsec1zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs4rm7hz
DATABASE_URL: postgres://postgres:postgres@postgres:5432/postgres DATABASE_URL: postgres://postgres:postgres@postgres:5432/postgres
POSTGRES_HOST_AUTH_METHOD: trust POSTGRES_HOST_AUTH_METHOD: trust
RUST_BACKTRACE: 1
artifacts:
when: always
paths:
- deno-test.xml
reports:
junit: deno-test.xml

45
.goosehints Normal file
View file

@ -0,0 +1,45 @@
# Ditto
This project is called Ditto, a self-hosted social media server written in TypeScript with Deno. It implements the [Nostr Protocol](https://raw.githubusercontent.com/nostr-protocol/nips/refs/heads/master/README.md), and parts of the [Mastodon API](https://docs.joinmastodon.org/methods/) and [Pleroma API](https://git.pleroma.social/pleroma/pleroma/-/raw/develop/docs/development/API/pleroma_api.md).
## Project Structure
Ditto is a monorepo with a `packages` directory. The main package is `packages/ditto`, and the main API definition is in `packages/ditto/app.ts`.
## Deno, npm, and jsr
Ditto uses Deno 2.x
Dependencies are managed in `deno.json`, which are added with the `deno add` command. This command also updates the `deno.lock` file. npm packages can be added by using `deno add` and prefixing the package name with an `npm:` protocol. For example, `deno add npm:kysely` would add the `kysely` package from npm.
[jsr](https://jsr.io/) is a modern alternative to npm. It's a completely different registry with different packages available. jsr packages can be added by using `deno add` and prefixing the package name with a `jsr:` protocol. For example, `deno add jsr:@std/assert` would add the `@std/assert` package from jsr.
## Nostr
Nostr is a decentralized social media protocol involving clients, relays, keys, and a unified Nostr event format.
Specifications on Nostr are called "NIPs". NIP stands for "Nostr Implementation Possibilities". NIPs are numbered like `NIP-XX` where `XX` are two capitalized hexadecimal digits, eg `NIP-01` and `NIP-C7`.
To learn about Nostr, use the fetch tool to read [NIP-01](https://raw.githubusercontent.com/nostr-protocol/nips/refs/heads/master/01.md).
To read a specific NIP, construct the NIP URL following this template: `https://raw.githubusercontent.com/nostr-protocol/nips/refs/heads/master/{nip}.md` (replace `{nip}` in the URL template with the relevant NIP name, eg `07` for NIP-07, or `C7` for NIP-C7). Then use the fetch tool to read the URL.
To read the definition of a specific kind, construct a URL following this template: `https://nostrbook.dev/kinds/{kind}.md` (replace `{kind}` in the template with the kind number, eg `https://nostrbook.dev/kinds/0.md` for kind 0).
To discover the full list of NIPs, use the fetch tool to read the [NIPs README](https://raw.githubusercontent.com/nostr-protocol/nips/refs/heads/master/README.md).
It's important that Ditto conforms to Nostr standards. Please read as much of the NIPs as you need to have a full understanding before adding or modifying Nostr events and filters. It is possible to add new ideas to Nostr that don't exist yet in the NIPs, but only after other options have been explored. Care must be taken when adding new Nostr ideas, to ensure they fit seamlessly within the existing Nostr ecosystem.
## How Ditto uses Nostr and Mastodon API
Ditto implements a full Nostr relay, available at `/relay` of the Ditto server.
Mastodon API functionality, available at `/api/*`, is built around the Nostr relay's storage implementation.
Ditto's goal is to enable Mastodon API clients to interact directly with Nostr. It achieves this by implementing most of Mastodon's API, and "pretending" to be a Mastodon server to client applications, while in actuality it uses Nostr as its decentralized protocol layer.
## Testing Changes
After making changes, please run `deno task check` to check for type errors. If there are any type errors, please try to fix them.
Afterwards, run `deno fmt` to format the code, and then you are done. Please do not try to run the server, or run any other tests.

View file

@ -1 +1 @@
deno 1.44.2 deno 2.2.2

2
.vscode/launch.json vendored
View file

@ -8,7 +8,7 @@
"request": "launch", "request": "launch",
"name": "Launch Program", "name": "Launch Program",
"type": "node", "type": "node",
"program": "${workspaceFolder}/src/server.ts", "program": "${workspaceFolder}/packages/ditto/server.ts",
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"runtimeExecutable": "deno", "runtimeExecutable": "deno",
"runtimeArgs": [ "runtimeArgs": [

View file

@ -2,5 +2,8 @@
"deno.enable": true, "deno.enable": true,
"deno.lint": true, "deno.lint": true,
"editor.defaultFormatter": "denoland.vscode-deno", "editor.defaultFormatter": "denoland.vscode-deno",
"path-intellisense.extensionOnImport": true "path-intellisense.extensionOnImport": true,
"files.associations": {
".goosehints": "markdown"
}
} }

View file

@ -7,9 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [1.1.0] - 2024-07-15
### Added
- Prometheus support (`/metrics` endpoint).
- Sort zaps by amount; add pagination.
### Fixed
- Added IP rate-limiting of HTTP requests and WebSocket messages.
- Added database query timeouts.
- Fixed nos2x compatibility.
## [1.0.0] - 2024-06-14 ## [1.0.0] - 2024-06-14
- Initial release - Initial release
[unreleased]: https://gitlab.com/soapbox-pub/ditto/-/compare/v1.0.0...HEAD [unreleased]: https://gitlab.com/soapbox-pub/ditto/-/compare/v1.1.0...HEAD
[1.1.0]: https://gitlab.com/soapbox-pub/ditto/-/compare/v1.0.0...v1.1.0
[1.0.0]: https://gitlab.com/soapbox-pub/ditto/-/tags/v1.0.0 [1.0.0]: https://gitlab.com/soapbox-pub/ditto/-/tags/v1.0.0

View file

@ -1,8 +1,10 @@
FROM denoland/deno:1.44.2 FROM denoland/deno:2.2.2
EXPOSE 4036 ENV PORT 5000
WORKDIR /app WORKDIR /app
RUN mkdir -p data && chown -R deno data RUN mkdir -p data && chown -R deno data
USER deno
COPY . . COPY . .
RUN deno cache src/server.ts RUN deno cache --allow-import packages/ditto/server.ts
RUN apt-get update && apt-get install -y unzip curl
RUN deno task soapbox
CMD deno task start CMD deno task start

View file

@ -7,8 +7,6 @@ For more info see: https://docs.soapbox.pub/ditto/
<img width="400" src="ditto-planet.png"> <img width="400" src="ditto-planet.png">
⚠️ This software is a work in progress.
## Features ## Features
- [x] Built-in Nostr relay - [x] Built-in Nostr relay
@ -18,9 +16,9 @@ For more info see: https://docs.soapbox.pub/ditto/
- [x] Reposts - [x] Reposts
- [x] Notifications - [x] Notifications
- [x] Profiles - [x] Profiles
- [ ] Search - [x] Search
- [x] Moderation - [x] Moderation
- [ ] Zaps - [x] Zaps
- [x] Customizable - [x] Customizable
- [x] Open source - [x] Open source
- [x] Self-hosted - [x] Self-hosted

117
deno.json
View file

@ -1,61 +1,114 @@
{ {
"$schema": "https://deno.land/x/deno@v1.41.0/cli/schemas/config-file.v1.json", "version": "1.1.0",
"workspace": [
"./packages/captcha",
"./packages/conf",
"./packages/db",
"./packages/ditto",
"./packages/lang",
"./packages/mastoapi",
"./packages/metrics",
"./packages/nip98",
"./packages/policies",
"./packages/ratelimiter",
"./packages/transcode",
"./packages/translators",
"./packages/uploaders",
"./packages/cashu"
],
"tasks": { "tasks": {
"start": "deno run -A src/server.ts", "start": "deno run -A --env-file --deny-read=.env packages/ditto/server.ts",
"dev": "deno run -A --watch src/server.ts", "dev": "deno run -A --env-file --deny-read=.env --watch packages/ditto/server.ts",
"hook": "deno run --allow-read --allow-run --allow-write https://deno.land/x/deno_hooks@0.1.1/mod.ts", "hook": "deno run --allow-read --allow-run --allow-write https://deno.land/x/deno_hooks@0.1.1/mod.ts",
"db:migrate": "deno run -A scripts/db-migrate.ts", "db:export": "deno run -A --env-file --deny-read=.env scripts/db-export.ts",
"debug": "deno run -A --inspect src/server.ts", "db:import": "deno run -A --env-file --deny-read=.env scripts/db-import.ts",
"test": "DATABASE_URL=\"sqlite://:memory:\" deno test -A --junit-path=./deno-test.xml", "db:cleanup": "deno run -A --env-file --deny-read=.env scripts/db-policy.ts",
"check": "deno check src/server.ts", "db:migrate": "deno run -A --env-file --deny-read=.env scripts/db-migrate.ts",
"nostr:pull": "deno run -A --env-file --deny-read=.env scripts/nostr-pull.ts",
"debug": "deno run -A --env-file --deny-read=.env --inspect packages/ditto/server.ts",
"test": "deno test -A --env-file=.env.test --deny-read=.env --junit-path=./deno-test.xml",
"check": "deno check --allow-import .",
"lint": "deno lint --allow-import",
"nsec": "deno run scripts/nsec.ts", "nsec": "deno run scripts/nsec.ts",
"admin:event": "deno run -A scripts/admin-event.ts", "admin:event": "deno run -A --env-file --deny-read=.env scripts/admin-event.ts",
"admin:role": "deno run -A scripts/admin-role.ts", "admin:role": "deno run -A --env-file --deny-read=.env scripts/admin-role.ts",
"setup": "deno run -A scripts/setup.ts", "setup": "deno run -A --env-file scripts/setup.ts",
"stats:recompute": "deno run -A scripts/stats-recompute.ts", "setup:kind0": "deno run -A --env-file --deny-read=.env scripts/setup-kind0.ts",
"soapbox": "curl -O https://dl.soapbox.pub/main/soapbox.zip && mkdir -p public && mv soapbox.zip public/ && cd public/ && unzip soapbox.zip && rm soapbox.zip" "stats:recompute": "deno run -A --env-file --deny-read=.env scripts/stats-recompute.ts",
"soapbox": "curl -O https://dl.soapbox.pub/main/soapbox.zip && mkdir -p public && mv soapbox.zip public/ && cd public/ && unzip -o soapbox.zip && rm soapbox.zip",
"trends": "deno run -A --env-file --deny-read=.env scripts/trends.ts",
"clean:deps": "deno cache --reload packages/ditto/app.ts",
"db:populate:nip05": "deno run -A --env-file --deny-read=.env scripts/db-populate-nip05.ts",
"db:populate-search": "deno run -A --env-file --deny-read=.env scripts/db-populate-search.ts",
"db:populate-extensions": "deno run -A --env-file --deny-read=.env scripts/db-populate-extensions.ts",
"db:streak:recompute": "deno run -A --env-file --deny-read=.env scripts/db-streak-recompute.ts",
"vapid": "deno run scripts/vapid.ts"
}, },
"unstable": ["cron", "ffi", "kv", "worker-options"], "unstable": [
"exclude": ["./public"], "cron",
"ffi",
"kv",
"worker-options"
],
"exclude": [
"./public"
],
"imports": { "imports": {
"@/": "./src/", "@b-fuze/deno-dom": "jsr:@b-fuze/deno-dom@^0.1.47",
"@bradenmacdonald/s3-lite-client": "jsr:@bradenmacdonald/s3-lite-client@^0.7.4", "@bradenmacdonald/s3-lite-client": "jsr:@bradenmacdonald/s3-lite-client@^0.7.4",
"@db/sqlite": "jsr:@db/sqlite@^0.11.1", "@cashu/cashu-ts": "npm:@cashu/cashu-ts@^2.2.0",
"@core/asyncutil": "jsr:@core/asyncutil@^1.2.0",
"@electric-sql/pglite": "npm:@electric-sql/pglite@^0.2.8",
"@esroyo/scoped-performance": "jsr:@esroyo/scoped-performance@^3.1.0",
"@gfx/canvas-wasm": "jsr:@gfx/canvas-wasm@^0.4.2",
"@hono/hono": "jsr:@hono/hono@^4.4.6",
"@isaacs/ttlcache": "npm:@isaacs/ttlcache@^1.4.1", "@isaacs/ttlcache": "npm:@isaacs/ttlcache@^1.4.1",
"@negrel/webpush": "jsr:@negrel/webpush@^0.3.0",
"@noble/secp256k1": "npm:@noble/secp256k1@^2.0.0", "@noble/secp256k1": "npm:@noble/secp256k1@^2.0.0",
"@nostrify/nostrify": "jsr:@nostrify/nostrify@^0.23.2", "@nostrify/db": "jsr:@nostrify/db@^0.39.4",
"@nostrify/nostrify": "jsr:@nostrify/nostrify@^0.39.1",
"@nostrify/policies": "jsr:@nostrify/policies@^0.36.1",
"@nostrify/types": "jsr:@nostrify/types@^0.36.0",
"@scure/base": "npm:@scure/base@^1.1.6", "@scure/base": "npm:@scure/base@^1.1.6",
"@sentry/deno": "https://deno.land/x/sentry@7.112.2/index.mjs", "@sentry/deno": "https://deno.land/x/sentry@7.112.2/index.mjs",
"@soapbox/kysely-deno-sqlite": "jsr:@soapbox/kysely-deno-sqlite@^2.1.0", "@soapbox/kysely-pglite": "jsr:@soapbox/kysely-pglite@^1.0.0",
"@soapbox/stickynotes": "jsr:@soapbox/stickynotes@^0.4.0", "@soapbox/logi": "jsr:@soapbox/logi@^0.3.0",
"@soapbox/safe-fetch": "jsr:@soapbox/safe-fetch@^2.0.0",
"@std/assert": "jsr:@std/assert@^0.225.1", "@std/assert": "jsr:@std/assert@^0.225.1",
"@std/async": "jsr:@std/async@^1.0.10",
"@std/cli": "jsr:@std/cli@^0.223.0", "@std/cli": "jsr:@std/cli@^0.223.0",
"@std/crypto": "jsr:@std/crypto@^0.224.0", "@std/crypto": "jsr:@std/crypto@^0.224.0",
"@std/dotenv": "jsr:@std/dotenv@^0.224.0",
"@std/encoding": "jsr:@std/encoding@^0.224.0", "@std/encoding": "jsr:@std/encoding@^0.224.0",
"@std/fs": "jsr:@std/fs@^0.229.3", "@std/fs": "jsr:@std/fs@^0.229.3",
"@std/json": "jsr:@std/json@^0.223.0", "@std/json": "jsr:@std/json@^0.223.0",
"@std/media-types": "jsr:@std/media-types@^0.224.1", "@std/media-types": "jsr:@std/media-types@^0.224.1",
"@std/streams": "jsr:@std/streams@^0.223.0", "@std/streams": "jsr:@std/streams@^0.223.0",
"@std/testing": "jsr:@std/testing@^1.0.9",
"blurhash": "npm:blurhash@2.0.5",
"comlink": "npm:comlink@^4.4.1", "comlink": "npm:comlink@^4.4.1",
"deno-safe-fetch/load": "https://gitlab.com/soapbox-pub/deno-safe-fetch/-/raw/v1.0.0/load.ts", "comlink-async-generator": "npm:comlink-async-generator@^0.0.1",
"commander": "npm:commander@12.1.0",
"entities": "npm:entities@^4.5.0", "entities": "npm:entities@^4.5.0",
"fast-stable-stringify": "npm:fast-stable-stringify@^1.0.0", "fast-stable-stringify": "npm:fast-stable-stringify@^1.0.0",
"formdata-helper": "npm:formdata-helper@^0.3.0", "formdata-helper": "npm:formdata-helper@^0.3.0",
"hono": "https://deno.land/x/hono@v3.10.1/mod.ts", "hono-rate-limiter": "npm:hono-rate-limiter@^0.3.0",
"hono/middleware": "https://deno.land/x/hono@v3.10.1/middleware.ts", "iso-639-1": "npm:iso-639-1@^3.1.5",
"iso-639-1": "npm:iso-639-1@2.1.15", "isomorphic-dompurify": "npm:isomorphic-dompurify@^2.16.0",
"isomorphic-dompurify": "npm:isomorphic-dompurify@^2.11.0", "kysely": "npm:kysely@^0.27.4",
"kysely": "npm:kysely@^0.27.3", "kysely-postgres-js": "npm:kysely-postgres-js@2.0.0",
"kysely_deno_postgres": "https://gitlab.com/soapbox-pub/kysely-deno-postgres/-/raw/main/mod.ts", "lande": "npm:lande@^1.0.10",
"light-bolt11-decoder": "npm:light-bolt11-decoder",
"linkify-plugin-hashtag": "npm:linkify-plugin-hashtag@^4.1.1", "linkify-plugin-hashtag": "npm:linkify-plugin-hashtag@^4.1.1",
"linkify-string": "npm:linkify-string@^4.1.1", "linkify-string": "npm:linkify-string@^4.1.1",
"linkifyjs": "npm:linkifyjs@^4.1.1", "linkifyjs": "npm:linkifyjs@^4.1.1",
"lru-cache": "npm:lru-cache@^10.2.2", "lru-cache": "npm:lru-cache@^10.2.2",
"nostr-relaypool": "npm:nostr-relaypool2@0.6.34",
"nostr-tools": "npm:nostr-tools@2.5.1", "nostr-tools": "npm:nostr-tools@2.5.1",
"nostr-wasm": "npm:nostr-wasm@^0.1.0", "nostr-wasm": "npm:nostr-wasm@^0.1.0",
"path-to-regexp": "npm:path-to-regexp@^7.1.0",
"postgres": "https://gitlab.com/soapbox-pub/postgres.js/-/raw/e79d7d2039446fbf7a37d4eca0d17e94a94b8b53/deno/mod.js",
"prom-client": "npm:prom-client@^15.1.2",
"question-deno": "https://raw.githubusercontent.com/ocpu/question-deno/10022b8e52555335aa510adb08b0a300df3cf904/mod.ts", "question-deno": "https://raw.githubusercontent.com/ocpu/question-deno/10022b8e52555335aa510adb08b0a300df3cf904/mod.ts",
"sharp": "npm:sharp@^0.33.5",
"tldts": "npm:tldts@^6.0.14", "tldts": "npm:tldts@^6.0.14",
"tseep": "npm:tseep@^1.2.1", "tseep": "npm:tseep@^1.2.1",
"type-fest": "npm:type-fest@^4.3.0", "type-fest": "npm:type-fest@^4.3.0",
@ -63,15 +116,7 @@
"zod": "npm:zod@^3.23.8", "zod": "npm:zod@^3.23.8",
"~/fixtures/": "./fixtures/" "~/fixtures/": "./fixtures/"
}, },
"lint": {
"include": ["src/", "scripts/"],
"rules": {
"tags": ["recommended"],
"exclude": ["no-explicit-any"]
}
},
"fmt": { "fmt": {
"include": ["src/", "scripts/"],
"useTabs": false, "useTabs": false,
"lineWidth": 120, "lineWidth": 120,
"indentWidth": 2, "indentWidth": 2,

2527
deno.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,23 +0,0 @@
# Authentication in Ditto
One of the main benefits of Nostr is that users control their keys. Instead of a username and password, the user has a public key (`npub` or `pubkey`) and private key (`nsec`). The public key is a globally-unique identifier for the user, and the private key can be used to sign events, producing a signature that only the pubkey could have produced.
With keys, users have full control over their identity. They can move between servers freely, and post to multiple servers at once. But with such power comes great responsibilities. Users cannot lose control of their key, or they'll lose control over their account forever.
## Managing Keys
There are several ways to manage keys in Nostr, and they all come with trade-offs. It's new territory, and people are still coming up with new ideas.
The main concerns are how to **conveniently log in on multiple devices**, and **who/what to trust with your key.**
### Current Solutions
1. **Private key text.** Users copy their key between devices/apps, giving apps full control over their key. Users might email the key to themselves, or better yet use a password manager, or apps might even provide a QR code for other apps to scan. This method is convenient, but it's not secure. Keys can get compromised in transit, or by a malicious or vulnerable app.
2. **Browser extension.** For web clients, an extension can expose `getPublicKey` and `signEvent` functions to web-pages without exposing the private key directly. This option is secure, but it only works well for laptop/desktop devices. On mobile, only FireFox can do it, with no support from Safari or Chrome. It also offers no way to share a key across devices on its own.
3. **Remote signer**. Users can run a remote signer program and then connect apps to it. The signer should be running 24/7, so it's best suited for running on a server. This idea has evolved into the creation of "bunker" services. Bunkers allow users to have a traditional username and password and login from anywhere. This method solves a lot of problems, but it also creates some problems. Users have to create an account on a separate website before they can log into your website. This makes it an option for more advanced users. Also, it's concerning that the administrator of the bunker server has full control over your keys. None of this is a problem if you run your own remote signer, but it's not a mainstream option.
4. **Custodial**. Apps which make you log you in with a username/password, and then keep Nostr keys for each user in their database. You might not even be able to export your keys. This option may be easier for users at first, but it puts a whole lot of liability on the server, since leaks can cause permanent damage. It also gives up a lot of the benefits of Nostr.
Each of these ideas could be improved upon greatly with new experiments and technical progress. But to Ditto, user freedom matters the most, so we're focusing on non-custodial solution. Even though there are security risks to copying around keys, the onus is on the user. The user may fall victim to a targeted attack (or make a stupid mistake), whereas custodial servers have the ability to wipe out entire demographics of users at once. Therefore we believe that custodial solutions are actually _less_ secure than users copying around keys. Users must take precautions about which apps to trust with their private key until we improve upon the area to make it more secure (likely with better support of browser extensions, OS key management, and more).

View file

@ -1,27 +0,0 @@
# Debugging Ditto
Running the command `deno task debug` will start the Ditto server in debug mode, making it possible to inspect with Chromium-based browsers by visiting `chrome://inspect`.
From there, go to the "Performance" tab and click "Start profiling". Perform the actions you want to profile, then click "Stop profiling". You can then inspect the call stack and see where the time is being spent.
## Remote debugging
If the Ditto server is on a separate machine, you will first need to put it into debug mode. Edit its systemd file (usually located at `/etc/systemd/system/ditto.service`) and change `deno task start` to `deno task debug` in the `ExecStart` line. Then run `systemctl daemon-reload` and `systemctl restart ditto`.
To access the debugger remotely, you can use SSH port forwarding. Run this command on your local machine, replacing `<user>@<host>` with the SSH login for the remote machine:
```sh
ssh -L 9229:localhost:9229 <user>@<host>
```
Then, in Chromium, go to `chrome://inspect` and the Ditto server should be available.
## SQLite performance
To track slow queries, first set `DEBUG=ditto:sqlite.worker` in the environment so only SQLite logs are shown.
Then, grep for any logs above 0.001s:
```sh
journalctl -fu ditto | grep -v '(0.00s)'
```

View file

@ -1,15 +0,0 @@
# Installing Ditto
First, install Deno:
```sh
curl -fsSL https://deno.land/x/install/install.sh | sudo DENO_INSTALL=/usr/local sh
```
Now, run Ditto:
```sh
deno run -A https://gitlab.com/soapbox-pub/ditto/-/raw/main/src/server.ts
```
That's it! Ditto is now running on your machine.

View file

@ -1,9 +0,0 @@
# Mastodon API
Ditto implements Mastodon's client-server API, a REST API used by Mastodon mobile apps and frontends to interact with Mastodon servers. While it was originally designed for Mastodon, it has been adopted by other ActivityPub servers such as Pleroma, Mitra, Friendica, and many others.
Note that Mastodon API is **not** ActivityPub. It is not the API used to federate between servers. Instead, it enables user interfaces, mobile apps, bots, and other clients to interact with Mastodon servers.
Mastodon is built in Ruby on Rails, and its API is inspired by Twitter's legacy REST API. Rails, being an MVC framework, has "models", which it maps directly to "Entities" in its API.
Endpoints return either a single Entity, or an array of Entities. Entities Entities are JSON objects with a specific structure, and are documented in the [Mastodon API documentation](https://docs.joinmastodon.org/api/).

291
fixtures/config-db.json Normal file
View file

@ -0,0 +1,291 @@
{
"configs": [{
"db": [
":soapbox_fe"
],
"group": ":pleroma",
"key": ":frontend_configurations",
"value": [
{
"tuple": [
":pleroma_fe",
{
":alwaysShowSubjectInput": true,
":background": "/images/city.jpg",
":collapseMessageWithSubject": false,
":disableChat": false,
":greentext": false,
":hideFilteredStatuses": false,
":hideMutedPosts": false,
":hidePostStats": false,
":hideSitename": false,
":hideUserStats": false,
":loginMethod": "password",
":logo": "/static/logo.svg",
":logoMargin": ".1em",
":logoMask": true,
":minimalScopesMode": false,
":noAttachmentLinks": false,
":nsfwCensorImage": "",
":postContentType": "text/plain",
":redirectRootLogin": "/main/friends",
":redirectRootNoLogin": "/main/all",
":scopeCopy": true,
":showFeaturesPanel": true,
":showInstanceSpecificPanel": false,
":sidebarRight": false,
":subjectLineBehavior": "email",
":theme": "pleroma-dark",
":webPushNotifications": false
}
]
},
{
"tuple": [
":soapbox_fe",
{
"aboutPages": {},
"ads": [
{
"card": {
"height": 564,
"image": "https://media.gleasonator.com/3c331456d0d0f9f9ad91eab0efbb4df22a044f92bdf6ef349b26de97db5ca3bd.png",
"type": "link",
"url": "https://www.veganbodybuilding.com/",
"width": 564
}
},
{
"card": {
"height": 250,
"image": "https://media.gleasonator.com/22590c7cb3edd8ac82660301be980c6fcad6b96a320e24f709ad0571a29ea0aa.png",
"type": "link",
"url": "https://poa.st",
"width": 300
}
}
],
"allowedEmoji": [
"👍",
"⚡",
"❤",
"😂",
"😯",
"😢",
"😡"
],
"authenticatedProfile": false,
"banner": "",
"betaPages": {},
"brandColor": "#1ca82b",
"colors": {
"accent": {
"100": "#eafae7",
"200": "#caf4c3",
"300": "#6bdf58",
"400": "#55da40",
"50": "#f4fdf3",
"500": "#2bd110",
"600": "#27bc0e",
"700": "#209d0c",
"800": "#0d3f05",
"900": "#082803"
},
"accent-blue": "#199727",
"danger": {
"100": "#fee2e2",
"200": "#fecaca",
"300": "#fca5a5",
"400": "#f87171",
"50": "#fef2f2",
"500": "#ef4444",
"600": "#dc2626",
"700": "#b91c1c",
"800": "#991b1b",
"900": "#7f1d1d"
},
"gradient-end": "#2bd110",
"gradient-start": "#1ca82b",
"gray": {
"100": "#f1f6f2",
"200": "#dde8de",
"300": "#9ebfa2",
"400": "#91b595",
"50": "#f8faf8",
"500": "#75a37a",
"600": "#69936e",
"700": "#4c504c",
"800": "#233125",
"900": "#161f17"
},
"greentext": "#789922",
"primary": {
"100": "#e8f6ea",
"200": "#c6e9ca",
"300": "#60c26b",
"400": "#49b955",
"50": "#f4fbf4",
"500": "#1ca82b",
"600": "#199727",
"700": "#157e20",
"800": "#08320d",
"900": "#052008"
},
"secondary": {
"100": "#eafae7",
"200": "#cef4c3",
"300": "#7cdf58",
"400": "#71da40",
"50": "#f9fdf3",
"500": "#359713",
"600": "#4ebc0e",
"700": "#2f9d0c",
"800": "#173f05",
"900": "#282828"
},
"success": {
"100": "#dcfce7",
"200": "#bbf7d0",
"300": "#86efac",
"400": "#4ade80",
"50": "#f0fdf4",
"500": "#22c55e",
"600": "#16a34a",
"700": "#15803d",
"800": "#166534",
"900": "#14532d"
}
},
"copyright": "♥2022. Copying is an act of love. Please copy and share.",
"cryptoAddresses": [
{
"address": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n",
"ticker": "btc"
},
{
"address": "0xAc9aB5Fc04Dc1cB1789Af75b523Bd23C70B2D717",
"ticker": "eth"
},
{
"address": "D5zVZs6jrRakaPVGiErkQiHt9sayzm6V5D",
"ticker": "doge"
},
{
"address": "0x541a45cb212b57f41393427fb15335fc89c35851",
"ticker": "ubq"
},
{
"address": "45JDCLrjJ4bgVUSbbs2yjy9m5Mf4VLPW8fG7jw9sq5u69rXZZopQogZNeyYkMBnXpkaip4p4QwaaJNhdTotPa9g44DBCzdK",
"ticker": "xmr"
},
{
"address": "ltc1qda645jdf4jszwxcvsn32ykdhemvlx7yl9n5gz9",
"ticker": "ltc"
},
{
"address": "bitcoincash:qpcfnm9w8uemax38yqhyg58zn2ptpf6szvkr0n48a7",
"ticker": "bch"
},
{
"address": "XnB5p4JvL3So91A1c1MERozZEjeMSsAD7J",
"ticker": "dash"
},
{
"address": "t1PHZX5ZjY7y61iC19A958W9hdyH3SiLJuF",
"ticker": "zec"
},
{
"address": "0xB81BAEE10d163404a1c60045a872a0da9E258465",
"ticker": "etc"
},
{
"address": "AGTLRXapPYpxt3PLdiXEs8y4kLw6Qy3C4t",
"ticker": "btg"
},
{
"address": "SbQcFUDi7kKyxkmskzW3w74x68H5eUrg76",
"ticker": "dgb"
},
{
"address": "N7nompUVxz5ATrzRVTzw7CaAJoSiVtEcQx",
"ticker": "nmc"
},
{
"address": "3AQcUgCbF6ymiR4HGCU8ANx9SqbzL6nx8r",
"ticker": "vtc"
}
],
"cryptoDonatePanel": {
"limit": 1
},
"customCss": [],
"defaultSettings": {
"themeMode": "system"
},
"displayFqn": true,
"extensions": {
"ads": {
"enabled": false,
"interval": 40,
"provider": "soapbox"
},
"patron": {
"enabled": true
}
},
"features": {
"accountAliases": true
},
"feedInjection": true,
"gdpr": false,
"greentext": true,
"logo": "https://media.gleasonator.com/0c760b3ecdbc993ba47b785d0adecf0ec71fd9c59808e27d0665b9f77a32d8de.png",
"mediaPreview": false,
"mobilePages": {},
"navlinks": {
"homeFooter": [
{
"title": "About",
"url": "/about"
},
{
"title": "Terms of Service",
"url": "/about/tos"
},
{
"title": "Privacy Policy",
"url": "/about/privacy"
},
{
"title": "DMCA",
"url": "/about/dmca"
},
{
"title": "Source Code",
"url": "/about#opensource"
}
]
},
"promoPanel": {
"items": [
{
"icon": "music",
"text": "Gleasonator theme song",
"url": "https://media.gleasonator.com/custom/261905_gleasonator_song.mp3"
}
]
},
"redirectRootNoLogin": "",
"sentryDsn": "https://95c1dd3284d7284134928059844ba086@o4505999744499712.ingest.sentry.io/4505999904931840",
"singleUserMode": false,
"singleUserModeProfile": "",
"tileServer": "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
"tileServerAttribution": "© OpenStreetMap Contributors",
"verifiedCanEditName": true,
"verifiedIcon": ""
}
]
}
]
}]
}

View file

@ -0,0 +1,9 @@
{
"kind": 0,
"id": "f7b1a3ca3fa77bffded2024568da939e8cd3ed2403004e1ecb56d556f299ad2a",
"pubkey": "82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2",
"created_at": 1715441226,
"tags": [],
"content": "{\"banner\":\"https:\\/\\/m.primal.net\\/IBZO.jpg\",\"website\":\"\",\"picture\":\"https:\\/\\/image.nostr.build\\/26867ce34e4b11f0a1d083114919a9f4eca699f3b007454c396ef48c43628315.jpg\",\"lud06\":\"\",\"display_name\":\"\",\"lud16\":\"jack@primal.net\",\"nip05\":\"\",\"name\":\"jack\",\"about\":\"bitcoin \u0026 chill\"}",
"sig": "9792ceb1e9c73a6c2140540ddbac4279361cae4cc41888019d9dd47d09c1e7cee55948f6e1af824fa0f856d892686352bc757ad157f766f0da656d5e80b38bc7"
}

View file

@ -0,0 +1,9 @@
{
"kind": 0,
"id": "34bc588a4ff5ca8570a1ad4114485239f83c135b09636dbc16df338f73079e42",
"pubkey": "47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4",
"created_at": 1726076335,
"tags": [],
"content": "{\"about\":\"Coding with nature's inspiration, embracing solitude's wisdom. Team Soapbox.\",\"bot\":false,\"lud16\":\"patrickreiis@getalby.com\",\"name\":\"patrickReiis\",\"nip05\":\"patrick@patrickdosreis.com\",\"picture\":\"https://image.nostr.build/2177817a323ed8a58d508fb25160e1c2f38f60256125b764c82c988869916e84.jpg\",\"website\":\"https://patrickdosreis.com/\",\"pubkey\":\"47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4\",\"npub\":\"npub1gujeqakgt7fyp6zjggxhyy7ft623qtcaay5lkc8n8gkry4cvnrzqd3f67z\",\"created_at\":1717600965}",
"sig": "2780887e58d6e59cc9c03cca8a583bc121d2c74d98cc434d22e65c1f56da1bb09d79fc7cc3c4ee5b829773c17d6f482b114dc951c1683c3908cedff783d785ad"
}

View file

@ -0,0 +1,13 @@
{
"kind": 1,
"id": "02e52f80e2e6a3ad0993e9c4a7b4e6afc79d067c6ff9c6df3fb2896342dee2df",
"pubkey": "47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4",
"created_at": 1724609131,
"tags": [
["e", "677c701036eae20632a7677ee6eece0c62e259d5c72864d78a3bbe419c0d2d2c", "wss://gleasonator.dev/relay", "root"],
["e", "677c701036eae20632a7677ee6eece0c62e259d5c72864d78a3bbe419c0d2d2c", "wss://gleasonator.dev/relay", "reply"],
["p", "82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2"]
],
"content": "Please I don't want to go back to the shoe factory",
"sig": "ce6ca329701eec5db0b182bd52c48777b9eccaac298180a6601d8c5156060d944768d71376e7d24c24cefb6619d1467f6a30e0ca574d68f748b38c784e4ced59"
}

View file

@ -0,0 +1,34 @@
{
"kind": 10002,
"id": "68fc04e23b07219f153a10947663b9dd7b271acbc03b82200e364e35de3e0bdd",
"pubkey": "0461fcbecc4c3374439932d6b8f11269ccdb7cc973ad7a50ae362db135a474dd",
"created_at": 1714969354,
"tags": [
[
"r",
"wss://gleasonator.dev/relay"
],
[
"r",
"wss://nosdrive.app/relay"
],
[
"r",
"wss://relay.mostr.pub/"
],
[
"r",
"wss://relay.primal.net/"
],
[
"r",
"wss://relay.snort.social/"
],
[
"r",
"wss://relay.damus.io/"
]
],
"content": "",
"sig": "cb7b1a75fe015d5c9481651379365bd5d098665b1bc7a453522177e2686eaa83581ec36f7a17429aad2541dad02c2c81023b81612f87f28fc57447fef1efab13"
}

View file

@ -0,0 +1,22 @@
{
"kind": 9735,
"id": "a57d30d59e7442f9a2ad329400a6cbf29c2b34b1e69e4cdce8bc2fe751d9268f",
"pubkey": "79f00d3f5a19ec806189fcab03c1be4ff81d18ee4f653c88fac41fe03570f432",
"created_at": 1724610766,
"tags": [
["p", "47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4"],
["e", "02e52f80e2e6a3ad0993e9c4a7b4e6afc79d067c6ff9c6df3fb2896342dee2df"],
["P", "82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2"],
[
"bolt11",
"lnbc52250n1pnvk7xvpp5l776w7354zz9mh7sf3dlq8znkfjhysse9dwda9c7se7jwpglng0qhp5jp5cqy7n7wz9jlvd0aa40ws0d3e78l4ug2pzfen2m56mwg0qahrscqzzsxqyz5vqsp5v30pn2u86h3mz69wlvmu9vam9wudlnt4fv9wcxn24s6vrkj842gq9qxpqysgqw9mfxpyce3fhfue8p88exx8g6gn5ut9c2tz8awnw377dmhqymszrsjg49waxprkd6ggdzn90dwpgjwhdtx45052ukylkwvu5q05w5lspyjpg37"
],
["preimage", "18264e7cce0b91bfd2016362e8a239591674c0f51ffa152acf5d73edac675432"],
[
"description",
"{\"id\":\"092cd6341b42604b8e908f5bed45cbd60d98bff33258ab4f83f24a7fad445065\",\"pubkey\":\"82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2\",\"created_at\":1724610762,\"kind\":9734,\"tags\":[[\"p\",\"47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4\"],[\"e\",\"02e52f80e2e6a3ad0993e9c4a7b4e6afc79d067c6ff9c6df3fb2896342dee2df\"],[\"amount\",\"5225000\"],[\"relays\",\"wss://relay.exit.pub\",\"wss://relay.damus.io\",\"wss://nos.lol\",\"wss://relay.mostr.pub\",\"wss://relay.primal.net\"]],\"content\":\"🫂\",\"sig\":\"84a36873000d5003c85c56996be856c598e91f66bf2cae9ee9d984892a11774310acf81eae2b40e9fbf25040b91239e840f856c44b68be2d23e4451fa6c5762a\"}"
]
],
"content": "🫂",
"sig": "087adfe3c5831e2d760678b2929f35340c35662929acb8050f0956a2a95ba2917bf610f921e3d3fc0c08a123c6f721574eb80ca469fe7e33b6581e976844bfcc"
}

View file

@ -1 +1,102 @@
{"authors":[{"pubkey":"17538dc2a62769d09443f18c37cbe358fab5bbf981173542aa7c5ff171ed77c4","followers_count":1386,"following_count":2108,"notes_count":805},{"pubkey":"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d","followers_count":7420,"following_count":478,"notes_count":446},{"pubkey":"3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24","followers_count":6999,"following_count":1428,"notes_count":801},{"pubkey":"7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19","followers_count":535,"following_count":962,"notes_count":59},{"pubkey":"97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322","followers_count":4199,"following_count":398,"notes_count":176},{"pubkey":"9be0be0e64d38a29a9cec9a5c8ef5d873c2bfa5362a4b558da5ff69bc3cbb81e","followers_count":695,"following_count":242,"notes_count":49},{"pubkey":"9ca0bd7450742d6a20319c0e3d4c679c9e046a9dc70e8ef55c2905e24052340b","followers_count":614,"following_count":301,"notes_count":566},{"pubkey":"c37b6a82a98de368c104bbc6da365571ec5a263b07057d0a3977b4c05afa7e63","followers_count":270,"following_count":361,"notes_count":589},{"pubkey":"fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52","followers_count":6902,"following_count":1,"notes_count":536}],"events":[{"event_id":"1c9ca83dfdc96bd795e0420904bdfeb81d9434aa69c88ce773f0e6e849b8e6cd","reposts_count":0,"replies_count":0,"reactions_count":3,"reactions":"{\"🔥\":2,\"🤙\":1}"},{"event_id":"2a6860b01ac1cb31c081a6cf93d2d83f7bb4a54d669414db61ead5602688a03e","reposts_count":0,"replies_count":0,"reactions_count":2,"reactions":"{\"🧡\":1,\"+\":1}"},{"event_id":"b1ed8ea342d0023a8bedcb79de77633f8f550a21e363e707dd260e411977cff4","reposts_count":0,"replies_count":0,"reactions_count":4,"reactions":"{\"🔥\":2,\"+\":2}"},{"event_id":"b8d7eff16cd1ead7c28032f9e36fd4ef2e29682f84e2a89f2fca8c2bec13385d","reposts_count":1,"replies_count":0,"reactions_count":4,"reactions":"{\"🤙\":1,\"+\":2,\"👌\":1}"},{"event_id":"cc127dc2528ad97eaa88ff37d6c5d6bbe94b163ca873701db64f9e1bcfaa40cb","reposts_count":2,"replies_count":0,"reactions_count":5,"reactions":"{\"💜\":1,\"🤙\":3,\"+\":1}"},{"event_id":"f331dc1c3985cf76b997dc9fadcb46241ba0ccb9d20159b0a3ca6f77f4316f58","reposts_count":0,"replies_count":0,"reactions_count":1,"reactions":"{\"+\":1}"}]} {
"authors": [
{
"pubkey": "17538dc2a62769d09443f18c37cbe358fab5bbf981173542aa7c5ff171ed77c4",
"followers_count": 1386,
"following_count": 2108,
"notes_count": 805
},
{
"pubkey": "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
"followers_count": 7420,
"following_count": 478,
"notes_count": 446
},
{
"pubkey": "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24",
"followers_count": 6999,
"following_count": 1428,
"notes_count": 801
},
{
"pubkey": "7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19",
"followers_count": 535,
"following_count": 962,
"notes_count": 59
},
{
"pubkey": "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322",
"followers_count": 4199,
"following_count": 398,
"notes_count": 176
},
{
"pubkey": "9be0be0e64d38a29a9cec9a5c8ef5d873c2bfa5362a4b558da5ff69bc3cbb81e",
"followers_count": 695,
"following_count": 242,
"notes_count": 49
},
{
"pubkey": "9ca0bd7450742d6a20319c0e3d4c679c9e046a9dc70e8ef55c2905e24052340b",
"followers_count": 614,
"following_count": 301,
"notes_count": 566
},
{
"pubkey": "c37b6a82a98de368c104bbc6da365571ec5a263b07057d0a3977b4c05afa7e63",
"followers_count": 270,
"following_count": 361,
"notes_count": 589
},
{
"pubkey": "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52",
"followers_count": 6902,
"following_count": 1,
"notes_count": 536
}
],
"events": [
{
"event_id": "1c9ca83dfdc96bd795e0420904bdfeb81d9434aa69c88ce773f0e6e849b8e6cd",
"reposts_count": 0,
"replies_count": 0,
"reactions_count": 3,
"reactions": "{\"🔥\":2,\"🤙\":1}"
},
{
"event_id": "2a6860b01ac1cb31c081a6cf93d2d83f7bb4a54d669414db61ead5602688a03e",
"reposts_count": 0,
"replies_count": 0,
"reactions_count": 2,
"reactions": "{\"🧡\":1,\"+\":1}"
},
{
"event_id": "b1ed8ea342d0023a8bedcb79de77633f8f550a21e363e707dd260e411977cff4",
"reposts_count": 0,
"replies_count": 0,
"reactions_count": 4,
"reactions": "{\"🔥\":2,\"+\":2}"
},
{
"event_id": "b8d7eff16cd1ead7c28032f9e36fd4ef2e29682f84e2a89f2fca8c2bec13385d",
"reposts_count": 1,
"replies_count": 0,
"reactions_count": 4,
"reactions": "{\"🤙\":1,\"+\":2,\"👌\":1}"
},
{
"event_id": "cc127dc2528ad97eaa88ff37d6c5d6bbe94b163ca873701db64f9e1bcfaa40cb",
"reposts_count": 2,
"replies_count": 0,
"reactions_count": 5,
"reactions": "{\"💜\":1,\"🤙\":3,\"+\":1}"
},
{
"event_id": "f331dc1c3985cf76b997dc9fadcb46241ba0ccb9d20159b0a3ca6f77f4316f58",
"reposts_count": 0,
"replies_count": 0,
"reactions_count": 1,
"reactions": "{\"+\":1}"
}
]
}

4999
grafana/Ditto-Dashboard.json Normal file

File diff suppressed because it is too large Load diff

34
installation/Caddyfile Normal file
View file

@ -0,0 +1,34 @@
# Cloudflare real IP configuration for rate-limiting
# {
# servers {
# # https://www.cloudflare.com/ips/
# trusted_proxies static 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32
# trusted_proxies_strict
# }
# }
example.com {
log
request_header X-Real-IP {client_ip}
@public path /packs/* /instance/* /images/* /favicon.ico /sw.js /sw.js.map
handle /packs/* {
root * /opt/ditto/public
header Cache-Control "max-age=31536000, public, immutable"
file_server
}
handle @public {
root * /opt/ditto/public
file_server
}
handle /metrics {
respond "Access denied" 403
}
handle {
reverse_proxy :4036
}
}

View file

@ -24,24 +24,13 @@ server {
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
root /opt/ditto/public; root /opt/ditto/public;
location @spa {
try_files /index.html /dev/null;
}
location @frontend {
try_files $uri @ditto-static;
}
location @ditto-static {
root /opt/ditto/static;
try_files $uri @spa;
}
location /packs { location /packs {
add_header Cache-Control "public, max-age=31536000, immutable"; add_header Cache-Control "public, max-age=31536000, immutable";
add_header Strict-Transport-Security "max-age=31536000" always; add_header Strict-Transport-Security "max-age=31536000" always;
@ -53,16 +42,13 @@ server {
try_files $uri =404; try_files $uri =404;
} }
location = /favicon.ico { location /metrics {
root /opt/ditto/static; allow 127.0.0.1;
try_files $uri =404; deny all;
}
location ~ ^/(api|relay|oauth|manifest.json|nodeinfo|.well-known/(nodeinfo|nostr.json)) {
proxy_pass http://ditto; proxy_pass http://ditto;
} }
location / { location / {
try_files /dev/null @frontend; proxy_pass http://ditto;
} }
} }

View file

@ -6,6 +6,7 @@ After=network-online.target
[Service] [Service]
Type=simple Type=simple
User=ditto User=ditto
SyslogIdentifier=ditto
WorkingDirectory=/opt/ditto WorkingDirectory=/opt/ditto
ExecStart=/usr/local/bin/deno task start ExecStart=/usr/local/bin/deno task start
Restart=on-failure Restart=on-failure

View file

@ -0,0 +1,9 @@
import { assert } from '@std/assert';
import { getCaptchaImages } from './assets.ts';
Deno.test('getCaptchaImages', async () => {
// If this function runs at all, it most likely worked.
const { bgImages } = await getCaptchaImages();
assert(bgImages.length);
});

View file

@ -0,0 +1,36 @@
import { type Image, loadImage } from '@gfx/canvas-wasm';
export interface CaptchaImages {
bgImages: Image[];
puzzleMask: Image;
puzzleHole: Image;
}
export async function getCaptchaImages(): Promise<CaptchaImages> {
const bgImages = await getBackgroundImages();
const puzzleMask = await loadImage(
await Deno.readFile(new URL('./assets/puzzle/puzzle-mask.png', import.meta.url)),
);
const puzzleHole = await loadImage(
await Deno.readFile(new URL('./assets/puzzle/puzzle-hole.png', import.meta.url)),
);
return { bgImages, puzzleMask, puzzleHole };
}
async function getBackgroundImages(): Promise<Image[]> {
const path = new URL('./assets/bg/', import.meta.url);
const images: Image[] = [];
for await (const dirEntry of Deno.readDir(path)) {
if (dirEntry.isFile && dirEntry.name.endsWith('.jpg')) {
const file = await Deno.readFile(new URL(dirEntry.name, path));
const image = await loadImage(file);
images.push(image);
}
}
return images;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View file

@ -0,0 +1,22 @@
Unsplash photos published before June 8, 2017 are CC0 (public domain):
Ashim D'Silva <https://unsplash.com/photos/WeYamle9fDM>
Canazei Granite Ridges <https://unsplash.com/photos/yrwpJwDNSHE>
Mr. Lee <https://unsplash.com/photos/v7r8kZStqFw>
Photo by SpaceX <https://unsplash.com/photos/VBNb52J8Trk>
Sunset by the Pier <https://unsplash.com/photos/ces8_Bo7bhQ>
Unsplash photos published on or after June 8, 2017 are free to use, modify, and redistribute subject to the Unsplash license <https://unsplash.com/license>:
Martin Adams <https://unsplash.com/photos/MpTdvXlAsVE>
Morskie Oko <https://unsplash.com/photos/_1UF_3TlKcQ>
Nattu Adnan <https://unsplash.com/photos/Ai2TRdvI6gM>
Tj Holowaychuk <https://unsplash.com/photos/iGrsa9rL11o>
Viktor Forgacs <https://unsplash.com/photos/q8XSCZYh6D8>
“A Large Body of Water Surrounded By Mountains” by Peter Thomas <https://unsplash.com/photos/Dxod5pdRtsk>
“A Trail of Footprints In The Sand” by David Emrich <https://unsplash.com/photos/A9mr3TPoj0k>
“Photo of Valley” by Aniket Doele <https://unsplash.com/photos/M6XC789HLe8>
Pexels photos are free to use, modify, and redistribute subject to the Pexels license <https://www.pexels.com/license/>:
Snow-Capped Mountain <https://www.pexels.com/photo/photo-of-snow-capped-mountain-during-evening-2440024/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="currentColor"
class="icon icon-tabler icons-tabler-filled icon-tabler-puzzle"
version="1.1"
id="svg2"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs2" /><path
stroke="none"
d="M0 0h24v24H0z"
fill="none"
id="path1" /><path
d="M10 2a3 3 0 0 1 2.995 2.824l.005 .176v1h3a2 2 0 0 1 1.995 1.85l.005 .15v3h1a3 3 0 0 1 .176 5.995l-.176 .005h-1v3a2 2 0 0 1 -1.85 1.995l-.15 .005h-3a2 2 0 0 1 -1.995 -1.85l-.005 -.15v-1a1 1 0 0 0 -1.993 -.117l-.007 .117v1a2 2 0 0 1 -1.85 1.995l-.15 .005h-3a2 2 0 0 1 -1.995 -1.85l-.005 -.15v-3a2 2 0 0 1 1.85 -1.995l.15 -.005h1a1 1 0 0 0 .117 -1.993l-.117 -.007h-1a2 2 0 0 1 -1.995 -1.85l-.005 -.15v-3a2 2 0 0 1 1.85 -1.995l.15 -.005h3v-1a3 3 0 0 1 3 -3z"
id="path2"
style="opacity:0.7" /><path
id="path2-3"
style="color:#000000;fill:#ffffff;-inkscape-stroke:none;opacity:0.9"
d="M 10,1 C 7.80271,1 6,2.80271 6,5 H 3.9824219 l -0.1875,0.00586 -0.019531,0.00195 C 2.2191757,5.1248607 0.99950612,6.4393901 1,8 v 3.017578 l 0.00586,0.1875 0.00195,0.01953 C 1.1244168,12.774924 2.429603,13.991286 3.9824219,14 l -0.1875,0.0059 -0.019531,0.002 C 2.2191756,14.12477 0.99950612,15.43939 1,17 v 3.017578 l 0.00586,0.1875 0.00195,0.01953 C 1.1248607,21.780826 2.4393901,23.000494 4,23 h 3.0175781 l 0.1875,-0.0059 0.019531,-0.002 C 8.7749229,22.875673 9.9912857,21.570397 10,20.017578 l 0.0059,0.1875 0.002,0.01953 C 10.12477,21.780824 11.43939,23.000494 13,23 h 3.017578 l 0.1875,-0.0059 0.01953,-0.002 C 17.780826,22.87523 19.000494,21.56061 19,20 v -2 h 0.01367 l 0.205078,-0.0059 h 0.01563 c 1.21751,-0.07037 2.231032,-0.615044 2.871094,-1.396485 0.64006,-0.78144 0.924537,-1.759302 0.896484,-2.714844 C 22.973903,12.92727 22.63402,11.969108 21.949219,11.226562 21.264413,10.484057 20.219542,9.9988247 19,10 V 7.9824219 l -0.0059,-0.1875 -0.002,-0.019531 C 18.87523,6.2191757 17.56061,4.9995061 16,5 H 14 V 4.9863281 L 13.994141,4.78125 V 4.765625 C 13.870457,2.6610112 12.108245,0.99988256 10,1 Z m 0,1 a 3,3 0 0 1 2.994141,2.8242188 L 13,5 v 1 h 3 a 2,2 0 0 1 1.994141,1.8496094 L 18,8 v 3 h 1 a 3,3 0 0 1 0.175781,5.994141 L 19,17 h -1 v 3 a 2,2 0 0 1 -1.849609,1.994141 L 16,22 H 13 A 2,2 0 0 1 11.005859,20.150391 L 11,20 V 19 A 1,1 0 0 0 9.0078125,18.882812 L 9,19 v 1 A 2,2 0 0 1 7.1503906,21.994141 L 7,22 H 4 A 2,2 0 0 1 2.0058594,20.150391 L 2,20 V 17 A 2,2 0 0 1 3.8496094,15.005859 L 4,15 H 5 A 1,1 0 0 0 5.1171875,13.007812 L 5,13 H 4 A 2,2 0 0 1 2.0058594,11.150391 L 2,11 V 8 A 2,2 0 0 1 3.8496094,6.0058594 L 4,6 H 7 V 5 a 3,3 0 0 1 3,-3 z" /></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 997 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" class="icon icon-tabler icons-tabler-filled icon-tabler-puzzle"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M10 2a3 3 0 0 1 2.995 2.824l.005 .176v1h3a2 2 0 0 1 1.995 1.85l.005 .15v3h1a3 3 0 0 1 .176 5.995l-.176 .005h-1v3a2 2 0 0 1 -1.85 1.995l-.15 .005h-3a2 2 0 0 1 -1.995 -1.85l-.005 -.15v-1a1 1 0 0 0 -1.993 -.117l-.007 .117v1a2 2 0 0 1 -1.85 1.995l-.15 .005h-3a2 2 0 0 1 -1.995 -1.85l-.005 -.15v-3a2 2 0 0 1 1.85 -1.995l.15 -.005h1a1 1 0 0 0 .117 -1.993l-.117 -.007h-1a2 2 0 0 1 -1.995 -1.85l-.005 -.15v-3a2 2 0 0 1 1.85 -1.995l.15 -.005h3v-1a3 3 0 0 1 3 -3z" /></svg>

After

Width:  |  Height:  |  Size: 696 B

View file

@ -0,0 +1,22 @@
import { createCanvas } from '@gfx/canvas-wasm';
import { assertNotEquals } from '@std/assert';
import { encodeHex } from '@std/encoding/hex';
import { addNoise } from './canvas.ts';
// This is almost impossible to truly test,
// but we can at least check that the image on the canvas changes.
Deno.test('addNoise', async () => {
const canvas = createCanvas(100, 100);
const ctx = canvas.getContext('2d');
const dataBefore = ctx.getImageData(0, 0, canvas.width, canvas.height);
const hashBefore = await crypto.subtle.digest('SHA-256', dataBefore.data);
addNoise(ctx, canvas.width, canvas.height);
const dataAfter = ctx.getImageData(0, 0, canvas.width, canvas.height);
const hashAfter = await crypto.subtle.digest('SHA-256', dataAfter.data);
assertNotEquals(encodeHex(hashBefore), encodeHex(hashAfter));
});

View file

@ -0,0 +1,21 @@
import type { CanvasRenderingContext2D } from '@gfx/canvas-wasm';
/**
* Add a small amount of noise to the image.
* This protects against an attacker pregenerating every possible solution and then doing a reverse-lookup.
*/
export function addNoise(ctx: CanvasRenderingContext2D, width: number, height: number): void {
const imageData = ctx.getImageData(0, 0, width, height);
// Loop over every pixel.
for (let i = 0; i < imageData.data.length; i += 4) {
// Add/subtract a small amount from each color channel.
// We skip i+3 because that's the alpha channel, which we don't want to modify.
for (let j = 0; j < 3; j++) {
const alteration = Math.floor(Math.random() * 11) - 5; // Vary between -5 and +5
imageData.data[i + j] = Math.min(Math.max(imageData.data[i + j] + alteration, 0), 255);
}
}
ctx.putImageData(imageData, 0, 0);
}

View file

@ -0,0 +1,12 @@
import { getCaptchaImages } from './assets.ts';
import { generateCaptcha, verifyCaptchaSolution } from './captcha.ts';
Deno.test('generateCaptcha', async () => {
const images = await getCaptchaImages();
generateCaptcha(images, { w: 370, h: 400 }, { w: 65, h: 65 });
});
Deno.test('verifyCaptchaSolution', () => {
verifyCaptchaSolution({ w: 65, h: 65 }, { x: 0, y: 0 }, { x: 0, y: 0 });
verifyCaptchaSolution({ w: 65, h: 65 }, { x: 0, y: 0 }, { x: 10, y: 10 });
});

View file

@ -0,0 +1,60 @@
import { createCanvas, type EmulatedCanvas2D } from '@gfx/canvas-wasm';
import { addNoise } from './canvas.ts';
import { areIntersecting, type Dimensions, type Point } from './geometry.ts';
import type { CaptchaImages } from './assets.ts';
/** Generate a puzzle captcha, returning canvases for the board and piece. */
export function generateCaptcha(
{ bgImages, puzzleMask, puzzleHole }: CaptchaImages,
bgSize: Dimensions,
puzzleSize: Dimensions,
): {
bg: EmulatedCanvas2D;
puzzle: EmulatedCanvas2D;
solution: Point;
} {
const bg = createCanvas(bgSize.w, bgSize.h);
const puzzle = createCanvas(puzzleSize.w, puzzleSize.h);
const ctx = bg.getContext('2d');
const pctx = puzzle.getContext('2d');
const solution = generateSolution(bgSize, puzzleSize);
const bgImage = bgImages[Math.floor(Math.random() * bgImages.length)];
// Draw the background image.
ctx.drawImage(bgImage, 0, 0, bg.width, bg.height);
addNoise(ctx, bg.width, bg.height);
// Draw the puzzle piece.
pctx.drawImage(puzzleMask, 0, 0, puzzle.width, puzzle.height);
pctx.globalCompositeOperation = 'source-in';
pctx.drawImage(bg, solution.x, solution.y, puzzle.width, puzzle.height, 0, 0, puzzle.width, puzzle.height);
// Draw the hole.
ctx.globalCompositeOperation = 'source-atop';
ctx.drawImage(puzzleHole, solution.x, solution.y, puzzle.width, puzzle.height);
return {
bg,
puzzle,
solution,
};
}
export function verifyCaptchaSolution(puzzleSize: Dimensions, point: Point, solution: Point): boolean {
return areIntersecting(
{ ...point, ...puzzleSize },
{ ...solution, ...puzzleSize },
);
}
/** Random coordinates such that the piece fits within the canvas. */
function generateSolution(bgSize: Dimensions, puzzleSize: Dimensions): Point {
return {
x: Math.floor(Math.random() * (bgSize.w - puzzleSize.w)),
y: Math.floor(Math.random() * (bgSize.h - puzzleSize.h)),
};
}

View file

@ -0,0 +1,7 @@
{
"name": "@ditto/captcha",
"version": "0.1.0",
"exports": {
".": "./mod.ts"
}
}

View file

@ -0,0 +1,8 @@
import { assertEquals } from '@std/assert';
import { areIntersecting } from './geometry.ts';
Deno.test('areIntersecting', () => {
assertEquals(areIntersecting({ x: 0, y: 0, w: 10, h: 10 }, { x: 5, y: 5, w: 10, h: 10 }), true);
assertEquals(areIntersecting({ x: 0, y: 0, w: 10, h: 10 }, { x: 15, y: 15, w: 10, h: 10 }), false);
});

View file

@ -0,0 +1,27 @@
export interface Point {
x: number;
y: number;
}
export interface Dimensions {
w: number;
h: number;
}
type Rectangle = Point & Dimensions;
/** Check if the two rectangles intersect by at least `threshold` percent. */
export function areIntersecting(rect1: Rectangle, rect2: Rectangle, threshold = 0.5): boolean {
const r1cx = rect1.x + rect1.w / 2;
const r2cx = rect2.x + rect2.w / 2;
const r1cy = rect1.y + rect1.h / 2;
const r2cy = rect2.y + rect2.h / 2;
const dist = Math.sqrt((r2cx - r1cx) ** 2 + (r2cy - r1cy) ** 2);
const e1 = Math.sqrt(rect1.h ** 2 + rect1.w ** 2) / 2;
const e2 = Math.sqrt(rect2.h ** 2 + rect2.w ** 2) / 2;
return dist <= (e1 + e2) * threshold;
}

2
packages/captcha/mod.ts Normal file
View file

@ -0,0 +1,2 @@
export { getCaptchaImages } from './assets.ts';
export { generateCaptcha, verifyCaptchaSolution } from './captcha.ts';

View file

@ -0,0 +1,457 @@
import { type NostrFilter, NSecSigner } from '@nostrify/nostrify';
import { NPostgres } from '@nostrify/db';
import { genEvent } from '@nostrify/nostrify/test';
import { generateSecretKey, getPublicKey } from 'nostr-tools';
import { bytesToString, stringToBytes } from '@scure/base';
import { assertEquals } from '@std/assert';
import { DittoPolyPg, TestDB } from '@ditto/db';
import { DittoConf } from '@ditto/conf';
import { getLastRedeemedNutzap, getMintsToProofs, getWallet, organizeProofs, validateAndParseWallet } from './cashu.ts';
Deno.test('validateAndParseWallet function returns valid data', async () => {
const conf = new DittoConf(Deno.env);
const orig = new DittoPolyPg(conf.databaseUrl);
await using db = new TestDB(orig);
await db.migrate();
await db.clear();
const store = new NPostgres(orig.kysely);
const sk = generateSecretKey();
const signer = new NSecSigner(sk);
const pubkey = await signer.getPublicKey();
const privkey = bytesToString('hex', sk);
const p2pk = getPublicKey(stringToBytes('hex', privkey));
// Wallet
const wallet = genEvent({
kind: 17375,
content: await signer.nip44.encrypt(
pubkey,
JSON.stringify([
['privkey', privkey],
['mint', 'https://mint.soul.com'],
]),
),
}, sk);
await store.event(wallet);
// Nutzap information
const nutzapInfo = genEvent({
kind: 10019,
tags: [
['pubkey', p2pk],
['mint', 'https://mint.soul.com'],
['relay', conf.relay],
],
}, sk);
await store.event(nutzapInfo);
const { data, error } = await validateAndParseWallet(store, signer, pubkey);
assertEquals(error, null);
assertEquals(data, {
wallet,
nutzapInfo,
privkey,
p2pk,
mints: ['https://mint.soul.com'],
relays: [conf.relay],
});
});
Deno.test('organizeProofs function is working', async () => {
const conf = new DittoConf(Deno.env);
const orig = new DittoPolyPg(conf.databaseUrl);
await using db = new TestDB(orig);
await db.migrate();
await db.clear();
const store = new NPostgres(orig.kysely);
const sk = generateSecretKey();
const signer = new NSecSigner(sk);
const pubkey = await signer.getPublicKey();
const event1 = genEvent({
kind: 7375,
content: await signer.nip44.encrypt(
pubkey,
JSON.stringify({
mint: 'https://mint.soul.com',
proofs: [
{
id: '005c2502034d4f12',
amount: 25,
secret: 'z+zyxAVLRqN9lEjxuNPSyRJzEstbl69Jc1vtimvtkPg=',
C: '0241d98a8197ef238a192d47edf191a9de78b657308937b4f7dd0aa53beae72c46',
},
{
id: '005c2502034d4f12',
amount: 25,
secret: 'z+zyxAVLRqN9lEjxuNPSyRJzEstbl69Jc1vtimvtkPg=',
C: '0241d98a8197ef238a192d47edf191a9de78b657308937b4f7dd0aa53beae72c46',
},
{
id: '005c2502034d4f12',
amount: 25,
secret: 'z+zyxAVLRqN9lEjxuNPSyRJzEstbl69Jc1vtimvtkPg=',
C: '0241d98a8197ef238a192d47edf191a9de78b657308937b4f7dd0aa53beae72c46',
},
{
id: '005c2502034d4f12',
amount: 25,
secret: 'z+zyxAVLRqN9lEjxuNPSyRJzEstbl69Jc1vtimvtkPg=',
C: '0241d98a8197ef238a192d47edf191a9de78b657308937b4f7dd0aa53beae72c46',
},
],
del: [],
}),
),
}, sk);
await store.event(event1);
const proof1 = {
'id': '004f7adf2a04356c',
'amount': 1,
'secret': '6780378b186cf7ada639ce4807803ad5e4a71217688430512f35074f9bca99c0',
'C': '03f0dd8df04427c8c53e4ae9ce8eb91c4880203d6236d1d745c788a5d7a47aaff3',
'dleq': {
'e': 'bd22fcdb7ede1edb52b9b8c6e1194939112928e7b4fc0176325e7671fb2bd351',
's': 'a9ad015571a0e538d62966a16d2facf806fb956c746a3dfa41fa689486431c67',
'r': 'b283980e30bf5a31a45e5e296e93ae9f20bf3a140c884b3b4cd952dbecc521df',
},
};
const token1 = JSON.stringify({
mint: 'https://mint-fashion.com',
proofs: [proof1],
del: [],
});
const event2 = genEvent({
kind: 7375,
content: await signer.nip44.encrypt(
pubkey,
token1,
),
}, sk);
await store.event(event2);
const proof2 = {
'id': '004f7adf2a04356c',
'amount': 123,
'secret': '6780378b186cf7ada639ce4807803ad5e4a71217688430512f35074f9bca99c0',
'C': '03f0dd8df04427c8c53e4ae9ce8eb91c4880203d6236d1d745c788a5d7a47aaff3',
'dleq': {
'e': 'bd22fcdb7ede1edb52b9b8c6e1194939112928e7b4fc0176325e7671fb2bd351',
's': 'a9ad015571a0e538d62966a16d2facf806fb956c746a3dfa41fa689486431c67',
'r': 'b283980e30bf5a31a45e5e296e93ae9f20bf3a140c884b3b4cd952dbecc521df',
},
};
const token2 = JSON.stringify({
mint: 'https://mint-fashion.com',
proofs: [proof2],
del: [],
});
const event3 = genEvent({
kind: 7375,
content: await signer.nip44.encrypt(
pubkey,
token2,
),
}, sk);
await store.event(event3);
const unspentProofs = await store.query([{ kinds: [7375], authors: [pubkey] }]);
const organizedProofs = await organizeProofs(unspentProofs, signer);
assertEquals(organizedProofs, {
'https://mint.soul.com': {
totalBalance: 100,
[event1.id]: { event: event1, balance: 100 },
},
'https://mint-fashion.com': {
totalBalance: 124,
[event2.id]: { event: event2, balance: 1 },
[event3.id]: { event: event3, balance: 123 },
},
});
});
Deno.test('getLastRedeemedNutzap function is working', async () => {
const conf = new DittoConf(Deno.env);
const orig = new DittoPolyPg(conf.databaseUrl);
await using db = new TestDB(orig);
await db.migrate();
await db.clear();
const store = new NPostgres(orig.kysely);
const sk = generateSecretKey();
const signer = new NSecSigner(sk);
const pubkey = await signer.getPublicKey();
const event1 = genEvent({
kind: 7376,
content: '<nip-44-encrypted>',
created_at: Math.floor(Date.now() / 1000), // now
tags: [
['e', '<event-id-of-created-token>', '', 'redeemed'],
],
}, sk);
await store.event(event1);
const event2 = genEvent({
kind: 7376,
content: '<nip-44-encrypted>',
created_at: Math.floor((Date.now() - 86400000) / 1000), // yesterday
tags: [
['e', '<event-id-of-created-token>', '', 'redeemed'],
],
}, sk);
await store.event(event2);
const event3 = genEvent({
kind: 7376,
content: '<nip-44-encrypted>',
created_at: Math.floor((Date.now() - 86400000) / 1000), // yesterday
tags: [
['e', '<event-id-of-created-token>', '', 'redeemed'],
],
}, sk);
await store.event(event3);
const event4 = genEvent({
kind: 7376,
content: '<nip-44-encrypted>',
created_at: Math.floor((Date.now() + 86400000) / 1000), // tomorrow
tags: [
['e', '<event-id-of-created-token>', '', 'redeemed'],
],
}, sk);
await store.event(event4);
const event = await getLastRedeemedNutzap(store, pubkey);
assertEquals(event, event4);
});
Deno.test('getMintsToProofs function is working', async () => {
const conf = new DittoConf(Deno.env);
const orig = new DittoPolyPg(conf.databaseUrl);
await using db = new TestDB(orig);
await db.migrate();
await db.clear();
const store = new NPostgres(orig.kysely);
const sk = generateSecretKey();
const signer = new NSecSigner(sk);
const pubkey = await signer.getPublicKey();
const redeemedNutzap = genEvent({
created_at: Math.floor(Date.now() / 1000), // now
kind: 9321,
content: 'Thanks buddy! Nice idea.',
tags: [
[
'proof',
JSON.stringify({
id: '005c2502034d4f12',
amount: 25,
secret: 'z+zyxAVLRqN9lEjxuNPSyRJzEstbl69Jc1vtimvtkPg=',
C: '0241d98a8197ef238a192d47edf191a9de78b657308937b4f7dd0aa53beae72c46',
}),
],
['u', 'https://mint.soul.com'],
['e', 'nutzapped-post'],
['p', '47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4'],
],
}, sk);
await store.event(redeemedNutzap);
await new Promise((r) => setTimeout(r, 1000));
const history = genEvent({
created_at: Math.floor(Date.now() / 1000), // now
kind: 7376,
content: 'nip-44-encrypted',
tags: [
['e', redeemedNutzap.id, conf.relay, 'redeemed'],
['p', redeemedNutzap.pubkey],
],
}, sk);
await store.event(history);
const nutzap = genEvent({
created_at: Math.floor(Date.now() / 1000), // now
kind: 9321,
content: 'Thanks buddy! Nice idea.',
tags: [
[
'proof',
JSON.stringify({
id: '005c2502034d4f12',
amount: 50,
secret: 'z+zyxAVLRqN9lEjxuNPSyRJzEstbl69Jc1vtimvtkPg=',
C: '0241d98a8197ef238a192d47edf191a9de78b657308937b4f7dd0aa53beae72c46',
}),
],
['u', 'https://mint.soul.com'],
['e', 'nutzapped-post'],
['p', '47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4'],
],
}, sk);
await store.event(nutzap);
const nutzapsFilter: NostrFilter = {
kinds: [9321],
'#p': ['47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4'],
'#u': ['https://mint.soul.com'],
};
const lastRedeemedNutzap = await getLastRedeemedNutzap(store, pubkey);
if (lastRedeemedNutzap) {
nutzapsFilter.since = lastRedeemedNutzap.created_at;
}
const mintsToProofs = await getMintsToProofs(store, nutzapsFilter, conf.relay);
assertEquals(mintsToProofs, {
'https://mint.soul.com': {
proofs: [{
id: '005c2502034d4f12',
amount: 50,
secret: 'z+zyxAVLRqN9lEjxuNPSyRJzEstbl69Jc1vtimvtkPg=',
C: '0241d98a8197ef238a192d47edf191a9de78b657308937b4f7dd0aa53beae72c46',
}],
toBeRedeemed: [
['e', nutzap.id, conf.relay, 'redeemed'],
['p', nutzap.pubkey],
],
},
});
});
Deno.test('getWallet function is working', async () => {
const conf = new DittoConf(Deno.env);
const orig = new DittoPolyPg(conf.databaseUrl);
await using db = new TestDB(orig);
await db.migrate();
await db.clear();
const sk = generateSecretKey();
const signer = new NSecSigner(sk);
const pubkey = await signer.getPublicKey();
const privkey = bytesToString('hex', sk);
const p2pk = getPublicKey(stringToBytes('hex', privkey));
const relay = new NPostgres(orig.kysely);
const proofs = genEvent({
kind: 7375,
content: await signer.nip44.encrypt(
pubkey,
JSON.stringify({
mint: 'https://cuiaba.mint.com',
proofs: [
{
'id': '004f7adf2a04356c',
'amount': 2,
'secret': '700312ccba84cb15d6a008c1d01b0dbf00025d3f2cb01f030a756553aca52de3',
'C': '02f0ff21fdd19a547d66d9ca09df5573ad88d28e4951825130708ba53cbed19561',
'dleq': {
'e': '9c44a58cb429be619c474b97216009bd96ff1b7dd145b35828a14f180c03a86f',
's': 'a11b8f616dfee5157a2c7c36da0ee181fe71b28729bee56b789e472c027ceb3b',
'r': 'c51b9ade8cfd3939b78d509c9723f86b43b432680f55a6791e3e252b53d4b465',
},
},
{
'id': '004f7adf2a04356c',
'amount': 4,
'secret': '5936f22d486734c03bd50b89aaa34be8e99f20d199bcebc09da8716890e95fb3',
'C': '039b55f92c02243e31b04e964f2ad0bcd2ed3229e334f4c7a81037392b8411d6e7',
'dleq': {
'e': '7b7be700f2515f1978ca27bc1045d50b9d146bb30d1fe0c0f48827c086412b9e',
's': 'cf44b08c7e64fd2bd9199667327b10a29b7c699b10cb7437be518203b25fe3fa',
'r': 'ec0cf54ce2d17fae5db1c6e5e5fd5f34d7c7df18798b8d92bcb7cb005ec2f93b',
},
},
{
'id': '004f7adf2a04356c',
'amount': 16,
'secret': '89e2315c058f3a010972dc6d546b1a2e81142614d715c28d169c6afdba5326bd',
'C': '02bc1c3756e77563fe6c7769fc9d9bc578ea0b84bf4bf045cf31c7e2d3f3ad0818',
'dleq': {
'e': '8dfa000c9e2a43d35d2a0b1c7f36a96904aed35457ca308c6e7d10f334f84e72',
's': '9270a914b1a53e32682b1277f34c5cfa931a6fab701a5dbee5855b68ddf621ab',
'r': 'ae71e572839a3273b0141ea2f626915592b4b3f5f91b37bbeacce0d3396332c9',
},
},
{
'id': '004f7adf2a04356c',
'amount': 16,
'secret': '06f2209f313d92505ae5c72087263f711b7a97b1b29a71886870e672a1b180ac',
'C': '02fa2ad933b62449e2765255d39593c48293f10b287cf7036b23570c8f01c27fae',
'dleq': {
'e': 'e696d61f6259ae97f8fe13a5af55d47f526eea62a7998bf888626fd1ae35e720',
's': 'b9f1ef2a8aec0e73c1a4aaff67e28b3ca3bc4628a532113e0733643c697ed7ce',
'r': 'b66ed62852811d14e9bf822baebfda92ba47c5c4babc4f2499d9ce81fbbbd3f2',
},
},
],
del: [],
}),
),
created_at: Math.floor(Date.now() / 1000), // now
}, sk);
await relay.event(proofs);
await relay.event(genEvent({
kind: 10019,
tags: [
['pubkey', p2pk],
['mint', 'https://mint.soul.com'],
['mint', 'https://cuiaba.mint.com'],
['relay', conf.relay],
],
}, sk));
const wallet = genEvent({
kind: 17375,
content: await signer.nip44.encrypt(
pubkey,
JSON.stringify([
['privkey', privkey],
['mint', 'https://mint.soul.com'],
]),
),
}, sk);
await relay.event(wallet);
const { wallet: walletEntity } = await getWallet(relay, pubkey, signer);
assertEquals(walletEntity, {
balance: 38,
mints: ['https://mint.soul.com', 'https://cuiaba.mint.com'],
relays: [conf.relay],
pubkey_p2pk: p2pk,
});
});

302
packages/cashu/cashu.ts Normal file
View file

@ -0,0 +1,302 @@
import type { Proof } from '@cashu/cashu-ts';
import { type NostrEvent, type NostrFilter, type NostrSigner, NSchema as n, type NStore } from '@nostrify/nostrify';
import { getPublicKey } from 'nostr-tools';
import { stringToBytes } from '@scure/base';
import { logi } from '@soapbox/logi';
import type { SetRequired } from 'type-fest';
import { z } from 'zod';
import { proofSchema, tokenEventSchema, type Wallet } from './schemas.ts';
type Data = {
wallet: NostrEvent;
nutzapInfo: NostrEvent;
privkey: string;
p2pk: string;
mints: string[];
relays: string[];
};
type CustomError =
| { message: 'Wallet not found'; code: 'wallet-not-found' }
| { message: 'Could not decrypt wallet content'; code: 'fail-decrypt-wallet' }
| { message: 'Could not parse wallet content'; code: 'fail-parse-wallet' }
| { message: 'Wallet does not contain privkey or privkey is not a valid nostr id'; code: 'privkey-missing' }
| { message: 'Nutzap information event not found'; code: 'nutzap-info-not-found' }
| {
message:
"You do not have a 'pubkey' tag in your nutzap information event or the one you have does not match the one derivated from the wallet.";
code: 'pubkey-mismatch';
}
| { message: 'You do not have any mints in your nutzap information event.'; code: 'mints-missing' };
/** Ensures that the wallet event and nutzap information event are correct. */
async function validateAndParseWallet(
store: NStore,
signer: SetRequired<NostrSigner, 'nip44'>,
pubkey: string,
opts?: { signal?: AbortSignal },
): Promise<{ data: Data; error: null } | { data: null; error: CustomError }> {
const [wallet] = await store.query([{ authors: [pubkey], kinds: [17375] }], { signal: opts?.signal });
if (!wallet) {
return { error: { message: 'Wallet not found', code: 'wallet-not-found' }, data: null };
}
let decryptedContent: string;
try {
decryptedContent = await signer.nip44.decrypt(pubkey, wallet.content);
} catch (e) {
logi({
level: 'error',
ns: 'ditto.api.cashu.wallet',
id: wallet.id,
kind: wallet.kind,
error: errorJson(e),
});
return { data: null, error: { message: 'Could not decrypt wallet content', code: 'fail-decrypt-wallet' } };
}
let contentTags: string[][];
try {
contentTags = n.json().pipe(z.string().array().array()).parse(decryptedContent);
} catch {
return { data: null, error: { message: 'Could not parse wallet content', code: 'fail-parse-wallet' } };
}
const privkey = contentTags.find(([value]) => value === 'privkey')?.[1];
if (!privkey || !isNostrId(privkey)) {
return {
data: null,
error: { message: 'Wallet does not contain privkey or privkey is not a valid nostr id', code: 'privkey-missing' },
};
}
const p2pk = getPublicKey(stringToBytes('hex', privkey));
const [nutzapInfo] = await store.query([{ authors: [pubkey], kinds: [10019] }], { signal: opts?.signal });
if (!nutzapInfo) {
return { data: null, error: { message: 'Nutzap information event not found', code: 'nutzap-info-not-found' } };
}
const nutzapInformationPubkey = nutzapInfo.tags.find(([name]) => name === 'pubkey')?.[1];
if (!nutzapInformationPubkey || (nutzapInformationPubkey !== p2pk)) {
return {
data: null,
error: {
message:
"You do not have a 'pubkey' tag in your nutzap information event or the one you have does not match the one derivated from the wallet.",
code: 'pubkey-mismatch',
},
};
}
const mints = [...new Set(nutzapInfo.tags.filter(([name]) => name === 'mint').map(([_, value]) => value))];
if (mints.length < 1) {
return {
data: null,
error: { message: 'You do not have any mints in your nutzap information event.', code: 'mints-missing' },
};
}
const relays = [...new Set(nutzapInfo.tags.filter(([name]) => name === 'relay').map(([_, value]) => value))];
return { data: { wallet, nutzapInfo, privkey, p2pk, mints, relays }, error: null };
}
type OrganizedProofs = {
[mintUrl: string]: {
/** Total balance in this mint */
totalBalance: number;
/** Event id */
[eventId: string]: {
event: NostrEvent;
/** Total balance in this event */
balance: number;
} | number;
};
};
async function organizeProofs(
events: NostrEvent[],
signer: SetRequired<NostrSigner, 'nip44'>,
): Promise<OrganizedProofs> {
const organizedProofs: OrganizedProofs = {};
const pubkey = await signer.getPublicKey();
for (const event of events) {
const decryptedContent = await signer.nip44.decrypt(pubkey, event.content);
const { data: token, success } = n.json().pipe(tokenEventSchema).safeParse(decryptedContent);
if (!success) {
continue;
}
const { mint, proofs } = token;
const balance = proofs.reduce((prev, current) => prev + current.amount, 0);
if (!organizedProofs[mint]) {
organizedProofs[mint] = { totalBalance: 0 };
}
organizedProofs[mint] = { ...organizedProofs[mint], [event.id]: { event, balance } };
organizedProofs[mint].totalBalance += balance;
}
return organizedProofs;
}
/** Returns a spending history event that contains the last redeemed nutzap. */
async function getLastRedeemedNutzap(
store: NStore,
pubkey: string,
opts?: { signal?: AbortSignal },
): Promise<NostrEvent | undefined> {
const events = await store.query([{ kinds: [7376], authors: [pubkey] }], { signal: opts?.signal });
for (const event of events) {
const nutzap = event.tags.find(([name]) => name === 'e');
const redeemed = nutzap?.[3];
if (redeemed === 'redeemed') {
return event;
}
}
}
/**
* toBeRedeemed are the nutzaps that will be redeemed into a kind 7375 and saved in the kind 7376 tags
* The tags format is: [
* [ "e", "<9321-event-id>", "<relay-hint>", "redeemed" ], // nutzap event that has been redeemed
* [ "p", "<sender-pubkey>" ] // pubkey of the author of the 9321 event (nutzap sender)
* ]
* https://github.com/nostr-protocol/nips/blob/master/61.md#updating-nutzap-redemption-history
*/
type MintsToProofs = { [key: string]: { proofs: Proof[]; toBeRedeemed: string[][] } };
/**
* Gets proofs from nutzaps that have not been redeemed yet.
* Each proof is associated with a specific mint.
* @param store Store used to query for the nutzaps
* @param nutzapsFilter Filter used to query for the nutzaps, most useful when
* it contains a 'since' field so it saves time and resources
* @param relay Relay hint where the new kind 7376 will be saved
* @returns MintsToProofs An object where each key is a mint url and the values are an array of proofs
* and an array of redeemed tags in this format:
* ```
* [
* ...,
* [ "e", "<9321-event-id>", "<relay-hint>", "redeemed" ], // nutzap event that has been redeemed
* [ "p", "<sender-pubkey>" ] // pubkey of the author of the 9321 event (nutzap sender)
* ]
* ```
*/
async function getMintsToProofs(
store: NStore,
nutzapsFilter: NostrFilter,
relay: string,
opts?: { signal?: AbortSignal },
): Promise<MintsToProofs> {
const mintsToProofs: MintsToProofs = {};
const nutzaps = await store.query([nutzapsFilter], { signal: opts?.signal });
for (const event of nutzaps) {
try {
const mint = event.tags.find(([name]) => name === 'u')?.[1];
if (!mint) {
continue;
}
const proofs = event.tags.filter(([name]) => name === 'proof').map((tag) => tag[1]).filter(Boolean);
if (proofs.length < 1) {
continue;
}
if (!mintsToProofs[mint]) {
mintsToProofs[mint] = { proofs: [], toBeRedeemed: [] };
}
const parsed = n.json().pipe(
proofSchema,
).array().safeParse(proofs);
if (!parsed.success) {
continue;
}
mintsToProofs[mint].proofs = [...mintsToProofs[mint].proofs, ...parsed.data];
mintsToProofs[mint].toBeRedeemed = [
...mintsToProofs[mint].toBeRedeemed,
[
'e', // nutzap event that has been redeemed
event.id,
relay,
'redeemed',
],
['p', event.pubkey], // pubkey of the author of the 9321 event (nutzap sender)
];
} catch (e) {
logi({ level: 'error', ns: 'ditto.api.cashu.wallet.swap', error: errorJson(e) });
}
}
return mintsToProofs;
}
/** Returns a wallet entity with the latest balance. */
async function getWallet(
store: NStore,
pubkey: string,
signer: SetRequired<NostrSigner, 'nip44'>,
opts?: { signal?: AbortSignal },
): Promise<{ wallet: Wallet; error: null } | { wallet: null; error: CustomError }> {
const { data, error } = await validateAndParseWallet(store, signer, pubkey, { signal: opts?.signal });
if (error) {
logi({ level: 'error', ns: 'ditto.cashu.get_wallet', error: errorJson(error) });
return { wallet: null, error };
}
const { p2pk, mints, relays } = data;
let balance = 0;
const tokens = await store.query([{ authors: [pubkey], kinds: [7375] }], { signal: opts?.signal });
for (const token of tokens) {
try {
const decryptedContent: { mint: string; proofs: Proof[] } = JSON.parse(
await signer.nip44.decrypt(pubkey, token.content),
);
if (!mints.includes(decryptedContent.mint)) {
mints.push(decryptedContent.mint);
}
balance += decryptedContent.proofs.reduce((accumulator, current) => {
return accumulator + current.amount;
}, 0);
} catch (e) {
logi({ level: 'error', ns: 'dtto.cashu.get_wallet', error: errorJson(e) });
}
}
// TODO: maybe change the 'Wallet' type data structure so each mint is a key and the value are the tokens associated with a given mint
const walletEntity: Wallet = {
pubkey_p2pk: p2pk,
mints,
relays,
balance,
};
return { wallet: walletEntity, error: null };
}
/** Serialize an error into JSON for JSON logging. */
export function errorJson(error: unknown): Error | null {
if (error instanceof Error) {
return error;
} else {
return null;
}
}
function isNostrId(value: unknown): boolean {
return n.id().safeParse(value).success;
}
export { getLastRedeemedNutzap, getMintsToProofs, getWallet, organizeProofs, validateAndParseWallet };

7
packages/cashu/deno.json Normal file
View file

@ -0,0 +1,7 @@
{
"name": "@ditto/cashu",
"version": "0.1.0",
"exports": {
".": "./mod.ts"
}
}

3
packages/cashu/mod.ts Normal file
View file

@ -0,0 +1,3 @@
export { getLastRedeemedNutzap, getMintsToProofs, getWallet, organizeProofs, validateAndParseWallet } from './cashu.ts';
export { proofSchema, tokenEventSchema, type Wallet, walletSchema } from './schemas.ts';
export { renderTransaction, type Transaction } from './views.ts';

View file

@ -0,0 +1,39 @@
import { NSchema as n } from '@nostrify/nostrify';
import { assertEquals } from '@std/assert';
import { proofSchema } from './schemas.ts';
import { tokenEventSchema } from './schemas.ts';
Deno.test('Parse proof', () => {
const proof =
'{"id":"004f7adf2a04356c","amount":1,"secret":"6780378b186cf7ada639ce4807803ad5e4a71217688430512f35074f9bca99c0","C":"03f0dd8df04427c8c53e4ae9ce8eb91c4880203d6236d1d745c788a5d7a47aaff3","dleq":{"e":"bd22fcdb7ede1edb52b9b8c6e1194939112928e7b4fc0176325e7671fb2bd351","s":"a9ad015571a0e538d62966a16d2facf806fb956c746a3dfa41fa689486431c67","r":"b283980e30bf5a31a45e5e296e93ae9f20bf3a140c884b3b4cd952dbecc521df"}}';
assertEquals(n.json().pipe(proofSchema).safeParse(proof).success, true);
assertEquals(n.json().pipe(proofSchema).safeParse(JSON.parse(proof)).success, false);
assertEquals(proofSchema.safeParse(JSON.parse(proof)).success, true);
assertEquals(proofSchema.safeParse(proof).success, false);
});
Deno.test('Parse token', () => {
const proof = {
'id': '004f7adf2a04356c',
'amount': 1,
'secret': '6780378b186cf7ada639ce4807803ad5e4a71217688430512f35074f9bca99c0',
'C': '03f0dd8df04427c8c53e4ae9ce8eb91c4880203d6236d1d745c788a5d7a47aaff3',
'dleq': {
'e': 'bd22fcdb7ede1edb52b9b8c6e1194939112928e7b4fc0176325e7671fb2bd351',
's': 'a9ad015571a0e538d62966a16d2facf806fb956c746a3dfa41fa689486431c67',
'r': 'b283980e30bf5a31a45e5e296e93ae9f20bf3a140c884b3b4cd952dbecc521df',
},
};
const token = JSON.stringify({
mint: 'https://mint-fashion.com',
proofs: [proof],
del: [],
});
assertEquals(n.json().pipe(tokenEventSchema).safeParse(token).success, true);
assertEquals(n.json().pipe(tokenEventSchema).safeParse(JSON.parse(token)).success, false);
assertEquals(tokenEventSchema.safeParse(JSON.parse(token)).success, true);
assertEquals(tokenEventSchema.safeParse(tokenEventSchema).success, false);
});

50
packages/cashu/schemas.ts Normal file
View file

@ -0,0 +1,50 @@
import { NSchema as n } from '@nostrify/nostrify';
import { z } from 'zod';
export const proofSchema: z.ZodType<{
id: string;
amount: number;
secret: string;
C: string;
dleq?: { s: string; e: string; r?: string };
dleqValid?: boolean;
}> = z.object({
id: z.string(),
amount: z.number(),
secret: z.string(),
C: z.string(),
dleq: z.object({ s: z.string(), e: z.string(), r: z.string().optional() })
.optional(),
dleqValid: z.boolean().optional(),
});
/** Decrypted content of a kind 7375 */
export const tokenEventSchema: z.ZodType<{
mint: string;
proofs: Array<z.infer<typeof proofSchema>>;
del?: string[];
}> = z.object({
mint: z.string().url(),
proofs: proofSchema.array(),
del: z.string().array().optional(),
});
/** Ditto Cashu wallet */
export const walletSchema: z.ZodType<{
pubkey_p2pk: string;
mints: string[];
relays: string[];
balance: number;
}> = z.object({
pubkey_p2pk: n.id(),
mints: z.array(z.string().url()).nonempty().transform((val) => {
return [...new Set(val)];
}),
relays: z.array(z.string()).nonempty().transform((val) => {
return [...new Set(val)];
}),
/** Unit in sats */
balance: z.number(),
});
export type Wallet = z.infer<typeof walletSchema>;

View file

@ -0,0 +1,85 @@
import { NSecSigner } from '@nostrify/nostrify';
import { NPostgres } from '@nostrify/db';
import { genEvent } from '@nostrify/nostrify/test';
import { generateSecretKey } from 'nostr-tools';
import { assertEquals } from '@std/assert';
import { DittoPolyPg, TestDB } from '@ditto/db';
import { DittoConf } from '@ditto/conf';
import { renderTransaction } from './views.ts';
Deno.test('renderTransaction function is working', async () => {
const conf = new DittoConf(Deno.env);
const orig = new DittoPolyPg(conf.databaseUrl);
await using db = new TestDB(orig);
await db.migrate();
await db.clear();
const sk = generateSecretKey();
const signer = new NSecSigner(sk);
const pubkey = await signer.getPublicKey();
const relay = new NPostgres(orig.kysely);
const history1 = genEvent({
kind: 7376,
content: await signer.nip44.encrypt(
pubkey,
JSON.stringify([
['direction', 'in'],
['amount', '33'],
]),
),
created_at: Math.floor(Date.now() / 1000), // now
}, sk);
await relay.event(history1);
const history2 = genEvent({
kind: 7376,
content: await signer.nip44.encrypt(
pubkey,
JSON.stringify([
['direction', 'out'],
['amount', '29'],
]),
),
created_at: Math.floor(Date.now() / 1000) - 1, // now - 1 second
}, sk);
await relay.event(history2);
const history3 = genEvent({
kind: 7376,
content: await signer.nip44.encrypt(
pubkey,
JSON.stringify([
['direction', 'ouch'],
['amount', 'yolo'],
]),
),
created_at: Math.floor(Date.now() / 1000) - 2, // now - 2 second
}, sk);
await relay.event(history3);
const events = await relay.query([{ kinds: [7376], authors: [pubkey], since: history2.created_at }]);
const transactions = await Promise.all(
events.map((event) => {
return renderTransaction(event, pubkey, signer);
}),
);
assertEquals(transactions, [
{
direction: 'in',
amount: 33,
created_at: history1.created_at,
},
{
direction: 'out',
amount: 29,
created_at: history2.created_at,
},
]);
});

44
packages/cashu/views.ts Normal file
View file

@ -0,0 +1,44 @@
import { type NostrEvent, type NostrSigner, NSchema as n } from '@nostrify/nostrify';
import type { SetRequired } from 'type-fest';
import { z } from 'zod';
type Transaction = {
amount: number;
created_at: number;
direction: 'in' | 'out';
};
/** Renders one history of transaction. */
async function renderTransaction(
event: NostrEvent,
viewerPubkey: string,
signer: SetRequired<NostrSigner, 'nip44'>,
): Promise<Transaction | undefined> {
if (event.kind !== 7376) return;
const { data: contentTags, success } = n.json().pipe(z.coerce.string().array().min(2).array()).safeParse(
await signer.nip44.decrypt(viewerPubkey, event.content),
);
if (!success) {
return;
}
const direction = contentTags.find(([name]) => name === 'direction')?.[1];
if (direction !== 'out' && direction !== 'in') {
return;
}
const amount = parseInt(contentTags.find(([name]) => name === 'amount')?.[1] ?? '', 10);
if (isNaN(amount)) {
return;
}
return {
created_at: event.created_at,
direction,
amount,
};
}
export { renderTransaction, type Transaction };

View file

@ -0,0 +1,54 @@
import { assertEquals, assertThrows } from '@std/assert';
import { DittoConf } from './DittoConf.ts';
Deno.test('DittoConfig', async (t) => {
const env = new Map<string, string>([
['DITTO_NSEC', 'nsec19shyxpuzd0cq2p5078fwnws7tyykypud6z205fzhlmlrs2vpz6hs83zwkw'],
]);
const config = new DittoConf(env);
await t.step('signer', async () => {
assertEquals(
await config.signer.getPublicKey(),
'1ba0c5ed1bbbf3b7eb0d7843ba16836a0201ea68a76bafcba507358c45911ff6',
);
});
});
Deno.test('DittoConfig defaults', async (t) => {
const env = new Map<string, string>();
const config = new DittoConf(env);
await t.step('signer throws', () => {
assertThrows(() => config.signer);
});
await t.step('port', () => {
assertEquals(config.port, 4036);
});
});
Deno.test('DittoConfig with insecure media host', () => {
const env = new Map<string, string>([
['LOCAL_DOMAIN', 'https://ditto.test'],
['MEDIA_DOMAIN', 'https://ditto.test'],
]);
assertThrows(
() => new DittoConf(env),
Error,
'For security reasons, MEDIA_DOMAIN cannot be on the same host as LOCAL_DOMAIN',
);
});
Deno.test('DittoConfig with insecure media host and precheck disabled', () => {
const env = new Map<string, string>([
['LOCAL_DOMAIN', 'https://ditto.test'],
['MEDIA_DOMAIN', 'https://ditto.test'],
['DITTO_PRECHECK', 'false'],
]);
new DittoConf(env);
});

516
packages/conf/DittoConf.ts Normal file
View file

@ -0,0 +1,516 @@
import os from 'node:os';
import path from 'node:path';
import { NSecSigner } from '@nostrify/nostrify';
import { decodeBase64 } from '@std/encoding/base64';
import { encodeBase64Url } from '@std/encoding/base64url';
import ISO6391, { type LanguageCode } from 'iso-639-1';
import { nip19 } from 'nostr-tools';
import { getEcdsaPublicKey } from './utils/crypto.ts';
import { optionalBooleanSchema, optionalNumberSchema } from './utils/schema.ts';
import { mergeURLPath } from './utils/url.ts';
/** Ditto application-wide configuration. */
export class DittoConf {
constructor(private env: { get(key: string): string | undefined }) {
if (this.precheck) {
const mediaUrl = new URL(this.mediaDomain);
if (this.url.host === mediaUrl.host) {
throw new Error(
'For security reasons, MEDIA_DOMAIN cannot be on the same host as LOCAL_DOMAIN.\n\nTo disable this check, set DITTO_PRECHECK="false"',
);
}
}
}
/** Cached parsed admin signer. */
private _signer: NSecSigner | undefined;
/** Cached parsed VAPID public key value. */
private _vapidPublicKey: Promise<string | undefined> | undefined;
/**
* Ditto admin secret key in hex format.
* @deprecated Use `signer` instead. TODO: handle auth tokens.
*/
get seckey(): Uint8Array {
const nsec = this.env.get('DITTO_NSEC');
if (!nsec) {
throw new Error('Missing DITTO_NSEC');
}
if (!nsec.startsWith('nsec1')) {
throw new Error('Invalid DITTO_NSEC');
}
return nip19.decode(nsec as `nsec1${string}`).data;
}
/** Ditto admin signer. */
get signer(): NSecSigner {
if (!this._signer) {
this._signer = new NSecSigner(this.seckey);
}
return this._signer;
}
/** Port to use when serving the HTTP server. */
get port(): number {
return parseInt(this.env.get('PORT') || '4036');
}
/** IP addresses not affected by rate limiting. */
get ipWhitelist(): string[] {
return this.env.get('IP_WHITELIST')?.split(',') || [];
}
/** Relay URL to the Ditto server's relay. */
get relay(): `wss://${string}` | `ws://${string}` {
const { protocol, host } = this.url;
return `${protocol === 'https:' ? 'wss:' : 'ws:'}//${host}/relay`;
}
/** Relay to use for NIP-50 `search` queries. */
get searchRelay(): string | undefined {
return this.env.get('SEARCH_RELAY');
}
/** Origin of the Ditto server, including the protocol and port. */
get localDomain(): string {
return this.env.get('LOCAL_DOMAIN') || `http://localhost:${this.port}`;
}
/** Link to an external nostr viewer. */
get externalDomain(): string {
return this.env.get('NOSTR_EXTERNAL') || 'https://njump.me';
}
/** Get a link to a nip19-encoded entity in the configured external viewer. */
external(path: string): string {
return new URL(path, this.externalDomain).toString();
}
/**
* Heroku-style database URL. This is used in production to connect to the
* database.
*
* Follows the format:
*
* ```txt
* protocol://username:password@host:port/database_name
* ```
*/
get databaseUrl(): string {
return this.env.get('DATABASE_URL') ?? 'file://data/pgdata';
}
/** PGlite debug level. 0 disables logging. */
get pgliteDebug(): 0 | 1 | 2 | 3 | 4 | 5 {
return Number(this.env.get('PGLITE_DEBUG') || 0) as 0 | 1 | 2 | 3 | 4 | 5;
}
get vapidPublicKey(): Promise<string | undefined> {
if (!this._vapidPublicKey) {
this._vapidPublicKey = (async () => {
const keys = await this.vapidKeys;
if (keys) {
const { publicKey } = keys;
const bytes = await crypto.subtle.exportKey('raw', publicKey);
return encodeBase64Url(bytes);
}
})();
}
return this._vapidPublicKey;
}
get vapidKeys(): Promise<CryptoKeyPair | undefined> {
return (async () => {
const encoded = this.env.get('VAPID_PRIVATE_KEY');
if (!encoded) {
return;
}
const keyData = decodeBase64(encoded);
const privateKey = await crypto.subtle.importKey(
'pkcs8',
keyData,
{ name: 'ECDSA', namedCurve: 'P-256' },
true,
['sign'],
);
const publicKey = await getEcdsaPublicKey(privateKey, true);
return { privateKey, publicKey };
})();
}
get db(): { timeouts: { default: number; relay: number; timelines: number } } {
const env = this.env;
return {
/** Database query timeout configurations. */
timeouts: {
/** Default query timeout when another setting isn't more specific. */
get default(): number {
return Number(env.get('DB_TIMEOUT_DEFAULT') || 5_000);
},
/** Timeout used for queries made through the Nostr relay. */
get relay(): number {
return Number(env.get('DB_TIMEOUT_RELAY') || 1_000);
},
/** Timeout used for timelines such as home, notifications, hashtag, etc. */
get timelines(): number {
return Number(env.get('DB_TIMEOUT_TIMELINES') || 15_000);
},
},
};
}
/** Time-to-live for captchas in milliseconds. */
get captchaTTL(): number {
return Number(this.env.get('CAPTCHA_TTL') || 5 * 60 * 1000);
}
/** Character limit to enforce for posts made through Mastodon API. */
get postCharLimit(): number {
return Number(this.env.get('POST_CHAR_LIMIT') || 5000);
}
/** S3 media storage configuration. */
get s3(): {
endPoint?: string;
region?: string;
accessKey?: string;
secretKey?: string;
bucket?: string;
pathStyle?: boolean;
port?: number;
sessionToken?: string;
useSSL?: boolean;
} {
const env = this.env;
return {
get endPoint(): string | undefined {
return env.get('S3_ENDPOINT');
},
get region(): string | undefined {
return env.get('S3_REGION');
},
get accessKey(): string | undefined {
return env.get('S3_ACCESS_KEY');
},
get secretKey(): string | undefined {
return env.get('S3_SECRET_KEY');
},
get bucket(): string | undefined {
return env.get('S3_BUCKET');
},
get pathStyle(): boolean | undefined {
return optionalBooleanSchema.parse(env.get('S3_PATH_STYLE'));
},
get port(): number | undefined {
return optionalNumberSchema.parse(env.get('S3_PORT'));
},
get sessionToken(): string | undefined {
return env.get('S3_SESSION_TOKEN');
},
get useSSL(): boolean | undefined {
return optionalBooleanSchema.parse(env.get('S3_USE_SSL'));
},
};
}
/** IPFS uploader configuration. */
get ipfs(): { apiUrl: string } {
const env = this.env;
return {
/** Base URL for private IPFS API calls. */
get apiUrl(): string {
return env.get('IPFS_API_URL') || 'http://localhost:5001';
},
};
}
/**
* The logging configuration for the Ditto server. The config is derived from
* the DEBUG environment variable and it is parsed as follows:
*
* `DEBUG='<jsonl|pretty>:<minimum log level to show>:comma-separated scopes to show'`.
* If the scopes are empty (e.g. in 'pretty:warn:', then all scopes are shown.)
*/
get logConfig(): {
fmt: 'jsonl' | 'pretty';
level: string;
scopes: string[];
} {
let [fmt, level, scopes] = (this.env.get('LOG_CONFIG') || '').split(':');
fmt ||= 'jsonl';
level ||= 'debug';
scopes ||= '';
if (fmt !== 'jsonl' && fmt !== 'pretty') fmt = 'jsonl';
return {
fmt: fmt as 'jsonl' | 'pretty',
level,
scopes: scopes.split(',').filter(Boolean),
};
}
/** nostr.build API endpoint when the `nostrbuild` uploader is used. */
get nostrbuildEndpoint(): string {
return this.env.get('NOSTRBUILD_ENDPOINT') || 'https://nostr.build/api/v2/upload/files';
}
/** Default Blossom servers to use when the `blossom` uploader is set. */
get blossomServers(): string[] {
return this.env.get('BLOSSOM_SERVERS')?.split(',') || ['https://blossom.primal.net/'];
}
/** Module to upload files with. */
get uploader(): string | undefined {
return this.env.get('DITTO_UPLOADER');
}
/** Location to use for local uploads. */
get uploadsDir(): string {
return this.env.get('UPLOADS_DIR') || 'data/uploads';
}
/** Media base URL for uploads. */
get mediaDomain(): string {
const value = this.env.get('MEDIA_DOMAIN');
if (!value) {
const url = this.url;
url.host = `media.${url.host}`;
return url.toString();
}
return value;
}
/**
* Whether to analyze media metadata with [blurhash](https://www.npmjs.com/package/blurhash) and [sharp](https://www.npmjs.com/package/sharp).
* This is prone to security vulnerabilities, which is why it's not enabled by default.
*/
get mediaAnalyze(): boolean {
return optionalBooleanSchema.parse(this.env.get('MEDIA_ANALYZE')) ?? false;
}
/** Whether to transcode uploaded video files with ffmpeg. */
get mediaTranscode(): boolean {
return optionalBooleanSchema.parse(this.env.get('MEDIA_TRANSCODE')) ?? false;
}
/** Max upload size for files in number of bytes. Default 100MiB. */
get maxUploadSize(): number {
return Number(this.env.get('MAX_UPLOAD_SIZE') || 100 * 1024 * 1024);
}
/** Usernames that regular users cannot sign up with. */
get forbiddenUsernames(): string[] {
return this.env.get('FORBIDDEN_USERNAMES')?.split(',') || [
'_',
'admin',
'administrator',
'root',
'sysadmin',
'system',
];
}
/** Domain of the Ditto server as a `URL` object, for easily grabbing the `hostname`, etc. */
get url(): URL {
return new URL(this.localDomain);
}
/** Merges the path with the localDomain. */
local(path: string): string {
return mergeURLPath(this.localDomain, path);
}
/** URL to send Sentry errors to. */
get sentryDsn(): string | undefined {
return this.env.get('SENTRY_DSN');
}
/** Postgres settings. */
get pg(): { poolSize: number } {
const env = this.env;
return {
/** Number of connections to use in the pool. */
get poolSize(): number {
return Number(env.get('PG_POOL_SIZE') ?? 20);
},
};
}
/** Whether to enable requesting events from known relays. */
get firehoseEnabled(): boolean {
return optionalBooleanSchema.parse(this.env.get('FIREHOSE_ENABLED')) ?? true;
}
/** Number of events the firehose is allowed to process at one time before they have to wait in a queue. */
get firehoseConcurrency(): number {
return Math.ceil(Number(this.env.get('FIREHOSE_CONCURRENCY') ?? 1));
}
/** Nostr event kinds of events to listen for on the firehose. */
get firehoseKinds(): number[] {
return (this.env.get('FIREHOSE_KINDS') ?? '0, 1, 3, 5, 6, 7, 20, 9735, 10002')
.split(/[, ]+/g)
.map(Number);
}
/**
* Whether Ditto should subscribe to Nostr events from the Postgres database itself.
* This would make Nostr events inserted directly into Postgres available to the streaming API and relay.
*/
get notifyEnabled(): boolean {
return optionalBooleanSchema.parse(this.env.get('NOTIFY_ENABLED')) ?? true;
}
/** Whether to enable Ditto cron jobs. */
get cronEnabled(): boolean {
return optionalBooleanSchema.parse(this.env.get('CRON_ENABLED')) ?? true;
}
/** User-Agent to use when fetching link previews. Pretend to be Facebook by default. */
get fetchUserAgent(): string {
return this.env.get('DITTO_FETCH_USER_AGENT') ?? 'facebookexternalhit';
}
/** Path to the custom policy module. Must be an absolute path, https:, npm:, or jsr: URI. */
get policy(): string {
return this.env.get('DITTO_POLICY') || path.join(this.dataDir, 'policy.ts');
}
/** Absolute path to the data directory used by Ditto. */
get dataDir(): string {
return this.env.get('DITTO_DATA_DIR') || path.join(Deno.cwd(), 'data');
}
/** Absolute path of the Deno directory. */
get denoDir(): string {
return this.env.get('DENO_DIR') || `${os.userInfo().homedir}/.cache/deno`;
}
/** Whether zap splits should be enabled. */
get zapSplitsEnabled(): boolean {
return optionalBooleanSchema.parse(this.env.get('ZAP_SPLITS_ENABLED')) ?? false;
}
/** Languages this server wishes to highlight. Used when querying trends.*/
get preferredLanguages(): LanguageCode[] | undefined {
return this.env.get('DITTO_LANGUAGES')?.split(',')?.filter(ISO6391.validate);
}
/** Mints to be displayed in the UI when the user decides to create a wallet.*/
get cashuMints(): string[] {
return this.env.get('CASHU_MINTS')?.split(',') ?? [];
}
/** Translation provider used to translate posts. */
get translationProvider(): string | undefined {
return this.env.get('TRANSLATION_PROVIDER');
}
/** DeepL URL endpoint. */
get deeplBaseUrl(): string | undefined {
return this.env.get('DEEPL_BASE_URL');
}
/** DeepL API KEY. */
get deeplApiKey(): string | undefined {
return this.env.get('DEEPL_API_KEY');
}
/** LibreTranslate URL endpoint. */
get libretranslateBaseUrl(): string | undefined {
return this.env.get('LIBRETRANSLATE_BASE_URL');
}
/** LibreTranslate API KEY. */
get libretranslateApiKey(): string | undefined {
return this.env.get('LIBRETRANSLATE_API_KEY');
}
/** Cache settings. */
get caches(): {
nip05: { max: number; ttl: number };
favicon: { max: number; ttl: number };
translation: { max: number; ttl: number };
} {
const env = this.env;
return {
/** NIP-05 cache settings. */
get nip05(): { max: number; ttl: number } {
return {
max: Number(env.get('DITTO_CACHE_NIP05_MAX') || 3000),
ttl: Number(env.get('DITTO_CACHE_NIP05_TTL') || 1 * 60 * 60 * 1000),
};
},
/** Favicon cache settings. */
get favicon(): { max: number; ttl: number } {
return {
max: Number(env.get('DITTO_CACHE_FAVICON_MAX') || 500),
ttl: Number(env.get('DITTO_CACHE_FAVICON_TTL') || 1 * 60 * 60 * 1000),
};
},
/** Translation cache settings. */
get translation(): { max: number; ttl: number } {
return {
max: Number(env.get('DITTO_CACHE_TRANSLATION_MAX') || 1000),
ttl: Number(env.get('DITTO_CACHE_TRANSLATION_TTL') || 6 * 60 * 60 * 1000),
};
},
};
}
/** Custom profile fields configuration. */
get profileFields(): { maxFields: number; nameLength: number; valueLength: number } {
const env = this.env;
return {
get maxFields(): number {
return Number(env.get('PROFILE_FIELDS_MAX_FIELDS') || 10);
},
get nameLength(): number {
return Number(env.get('PROFILE_FIELDS_NAME_LENGTH') || 255);
},
get valueLength(): number {
return Number(env.get('PROFILE_FIELDS_VALUE_LENGTH') || 2047);
},
};
}
/** Maximum time between events before a streak is broken, *in seconds*. */
get streakWindow(): number {
return Number(this.env.get('STREAK_WINDOW') || 129600);
}
/** Whether to perform security/configuration checks on startup. */
get precheck(): boolean {
return optionalBooleanSchema.parse(this.env.get('DITTO_PRECHECK')) ?? true;
}
/** Path to `ffmpeg` executable. */
get ffmpegPath(): string {
return this.env.get('FFMPEG_PATH') || 'ffmpeg';
}
/** Path to `ffprobe` executable. */
get ffprobePath(): string {
return this.env.get('FFPROBE_PATH') || 'ffprobe';
}
}

7
packages/conf/deno.json Normal file
View file

@ -0,0 +1,7 @@
{
"name": "@ditto/conf",
"version": "0.1.0",
"exports": {
".": "./mod.ts"
}
}

1
packages/conf/mod.ts Normal file
View file

@ -0,0 +1 @@
export { DittoConf } from './DittoConf.ts';

View file

@ -0,0 +1,28 @@
import { assertEquals } from '@std/assert';
import { getEcdsaPublicKey } from './crypto.ts';
Deno.test('getEcdsaPublicKey', async () => {
const { publicKey, privateKey } = await crypto.subtle.generateKey(
{
name: 'ECDSA',
namedCurve: 'P-256',
},
true,
['sign', 'verify'],
);
const result = await getEcdsaPublicKey(privateKey, true);
assertKeysEqual(result, publicKey);
});
/** Assert that two CryptoKey objects are equal by value. Keys must be exportable. */
async function assertKeysEqual(a: CryptoKey, b: CryptoKey): Promise<void> {
const [jwk1, jwk2] = await Promise.all([
crypto.subtle.exportKey('jwk', a),
crypto.subtle.exportKey('jwk', b),
]);
assertEquals(jwk1, jwk2);
}

View file

@ -0,0 +1,25 @@
/**
* Convert an ECDSA private key into a public key.
* https://stackoverflow.com/a/72153942
*/
export async function getEcdsaPublicKey(
privateKey: CryptoKey,
extractable: boolean,
): Promise<CryptoKey> {
if (privateKey.type !== 'private') {
throw new Error('Expected a private key.');
}
if (privateKey.algorithm.name !== 'ECDSA') {
throw new Error('Expected a private key with the ECDSA algorithm.');
}
const jwk = await crypto.subtle.exportKey('jwk', privateKey);
const keyUsages: KeyUsage[] = ['verify'];
// Remove the private property from the JWK.
delete jwk.d;
jwk.key_ops = keyUsages;
jwk.ext = extractable;
return crypto.subtle.importKey('jwk', jwk, privateKey.algorithm, extractable, keyUsages);
}

View file

@ -0,0 +1,17 @@
import { assertEquals, assertThrows } from '@std/assert';
import { optionalBooleanSchema, optionalNumberSchema } from './schema.ts';
Deno.test('optionalBooleanSchema', () => {
assertEquals(optionalBooleanSchema.parse('true'), true);
assertEquals(optionalBooleanSchema.parse('false'), false);
assertEquals(optionalBooleanSchema.parse(undefined), undefined);
assertThrows(() => optionalBooleanSchema.parse('invalid'));
});
Deno.test('optionalNumberSchema', () => {
assertEquals(optionalNumberSchema.parse('123'), 123);
assertEquals(optionalNumberSchema.parse('invalid'), NaN); // maybe this should throw?
assertEquals(optionalNumberSchema.parse(undefined), undefined);
});

View file

@ -0,0 +1,11 @@
import { z } from 'zod';
export const optionalBooleanSchema = z
.enum(['true', 'false'])
.optional()
.transform((value) => value !== undefined ? value === 'true' : undefined);
export const optionalNumberSchema = z
.string()
.optional()
.transform((value) => value !== undefined ? Number(value) : undefined);

View file

@ -0,0 +1,9 @@
import { assertEquals } from '@std/assert';
import { mergeURLPath } from './url.ts';
Deno.test('mergeURLPath', () => {
assertEquals(mergeURLPath('https://mario.com', '/path'), 'https://mario.com/path');
assertEquals(mergeURLPath('https://mario.com', 'https://luigi.com/path'), 'https://mario.com/path');
assertEquals(mergeURLPath('https://mario.com', 'https://luigi.com/path?q=1'), 'https://mario.com/path?q=1');
});

View file

@ -0,0 +1,23 @@
/**
* Produce a URL whose origin is guaranteed to be the same as the base URL.
* The path is either an absolute path (starting with `/`), or a full URL. In either case, only its path is used.
*/
export function mergeURLPath(
/** Base URL. Result is guaranteed to use this URL's origin. */
base: string,
/** Either an absolute path (starting with `/`), or a full URL. If a full URL, its path */
path: string,
): string {
const url = new URL(
path.startsWith('/') ? path : new URL(path).pathname,
base,
);
if (!path.startsWith('/')) {
// Copy query parameters from the original URL to the new URL
const originalUrl = new URL(path);
url.search = originalUrl.search;
}
return url.toString();
}

16
packages/db/DittoDB.ts Normal file
View file

@ -0,0 +1,16 @@
import type { Kysely } from 'kysely';
import type { DittoTables } from './DittoTables.ts';
export interface DittoDB extends AsyncDisposable {
readonly kysely: Kysely<DittoTables>;
readonly poolSize: number;
readonly availableConnections: number;
migrate(): Promise<void>;
listen(channel: string, callback: (payload: string) => void): void;
}
export interface DittoDBOpts {
poolSize?: number;
debug?: 0 | 1 | 2 | 3 | 4 | 5;
}

View file

@ -0,0 +1,52 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import { logi } from '@soapbox/logi';
import { FileMigrationProvider, type Kysely, Migrator } from 'kysely';
import type { JsonValue } from '@std/json';
export class DittoPgMigrator {
private migrator: Migrator;
// deno-lint-ignore no-explicit-any
constructor(private kysely: Kysely<any>) {
this.migrator = new Migrator({
db: this.kysely,
provider: new FileMigrationProvider({
fs,
path,
migrationFolder: new URL(import.meta.resolve('./migrations')).pathname,
}),
});
}
async migrate(): Promise<void> {
logi({ level: 'info', ns: 'ditto.db.migration', msg: 'Running migrations...', state: 'started' });
const { results, error } = await this.migrator.migrateToLatest();
if (error) {
logi({
level: 'fatal',
ns: 'ditto.db.migration',
msg: 'Migration failed.',
state: 'failed',
results: results as unknown as JsonValue,
error: error instanceof Error ? error : null,
});
throw new Error('Migration failed.');
} else {
if (!results?.length) {
logi({ level: 'info', ns: 'ditto.db.migration', msg: 'Everything up-to-date.', state: 'skipped' });
} else {
logi({
level: 'info',
ns: 'ditto.db.migration',
msg: 'Migrations finished!',
state: 'migrated',
results: results as unknown as JsonValue,
});
}
}
}
}

View file

@ -0,0 +1,90 @@
import type { NPostgresSchema } from '@nostrify/db';
import type { Generated } from 'kysely';
import type { MastodonPreviewCard } from '@ditto/mastoapi/types';
export interface DittoTables extends NPostgresSchema {
auth_tokens: AuthTokenRow;
author_stats: AuthorStatsRow;
domain_favicons: DomainFaviconRow;
event_stats: EventStatsRow;
event_zaps: EventZapRow;
push_subscriptions: PushSubscriptionRow;
/** This is a materialized view of `author_stats` pre-sorted by followers_count. */
top_authors: Pick<AuthorStatsRow, 'pubkey' | 'followers_count' | 'search'>;
}
interface AuthorStatsRow {
pubkey: string;
followers_count: number;
following_count: number;
notes_count: number;
search: string;
streak_start: number | null;
streak_end: number | null;
nip05: string | null;
nip05_domain: string | null;
nip05_hostname: string | null;
nip05_last_verified_at: number | null;
}
interface EventStatsRow {
event_id: string;
replies_count: number;
reposts_count: number;
reactions_count: number;
quotes_count: number;
reactions: string;
zaps_amount: number;
zaps_amount_cashu: number;
link_preview?: MastodonPreviewCard;
}
interface AuthTokenRow {
token_hash: Uint8Array;
pubkey: string;
bunker_pubkey: string;
nip46_sk_enc: Uint8Array;
nip46_relays: string[];
created_at: Date;
}
interface DomainFaviconRow {
domain: string;
favicon: string;
last_updated_at: number;
}
interface EventZapRow {
receipt_id: string;
target_event_id: string;
sender_pubkey: string;
amount_millisats: number;
comment: string;
}
interface PushSubscriptionRow {
id: Generated<bigint>;
pubkey: string;
token_hash: Uint8Array;
endpoint: string;
p256dh: string;
auth: string;
data: {
alerts?: {
mention?: boolean;
status?: boolean;
reblog?: boolean;
follow?: boolean;
follow_request?: boolean;
favourite?: boolean;
poll?: boolean;
update?: boolean;
'admin.sign_up'?: boolean;
'admin.report'?: boolean;
};
policy?: 'all' | 'followed' | 'follower' | 'none';
} | null;
created_at: Generated<Date>;
updated_at: Generated<Date>;
}

View file

@ -0,0 +1,41 @@
import { dbQueriesCounter, dbQueryDurationHistogram } from '@ditto/metrics';
import { logi, type LogiValue } from '@soapbox/logi';
import type { Logger } from 'kysely';
/** Log the SQL for queries. */
export const KyselyLogger: Logger = (event) => {
const { query, queryDurationMillis } = event;
const { parameters, sql } = query;
const duration = queryDurationMillis / 1000;
dbQueriesCounter.inc();
dbQueryDurationHistogram.observe(duration);
if (event.level === 'query') {
logi({ level: 'trace', ns: 'ditto.sql', sql, parameters: parameters as LogiValue, duration });
}
if (event.level === 'error') {
if (event.error instanceof Error) {
switch (event.error.message) {
case 'duplicate key value violates unique constraint "nostr_events_pkey"':
case 'duplicate key value violates unique constraint "author_stats_pkey"':
case 'duplicate key value violates unique constraint "event_stats_pkey"':
case 'duplicate key value violates unique constraint "event_zaps_pkey"':
case 'insert or update on table "event_stats" violates foreign key constraint "event_stats_event_id_fkey"':
return; // Don't log expected errors
}
}
logi({
level: 'error',
ns: 'ditto.sql',
sql,
parameters: parameters as LogiValue,
error: event.error instanceof Error ? event.error : null,
duration,
});
}
};

View file

@ -0,0 +1,22 @@
import { assertEquals, assertRejects } from '@std/assert';
import { DittoPglite } from './DittoPglite.ts';
Deno.test('DittoPglite', async () => {
await using db = new DittoPglite('memory://');
await db.migrate();
assertEquals(db.poolSize, 1);
assertEquals(db.availableConnections, 1);
});
Deno.test('DittoPglite query after closing', async () => {
const db = new DittoPglite('memory://');
await db[Symbol.asyncDispose]();
await assertRejects(
() => db.kysely.selectFrom('nostr_events').selectAll().execute(),
Error,
'PGlite is closed',
);
});

View file

@ -0,0 +1,62 @@
import { PGlite } from '@electric-sql/pglite';
import { pg_trgm } from '@electric-sql/pglite/contrib/pg_trgm';
import { PgliteDialect } from '@soapbox/kysely-pglite';
import { Kysely } from 'kysely';
import { KyselyLogger } from '../KyselyLogger.ts';
import { DittoPgMigrator } from '../DittoPgMigrator.ts';
import { isWorker } from '../utils/worker.ts';
import type { DittoDB, DittoDBOpts } from '../DittoDB.ts';
import type { DittoTables } from '../DittoTables.ts';
export class DittoPglite implements DittoDB {
readonly poolSize = 1;
readonly availableConnections = 1;
readonly kysely: Kysely<DittoTables>;
private pglite: PGlite;
private migrator: DittoPgMigrator;
constructor(databaseUrl: string, opts?: DittoDBOpts) {
const url = new URL(databaseUrl);
if (url.protocol === 'file:' && isWorker()) {
throw new Error('PGlite is not supported in worker threads.');
}
this.pglite = new PGlite(databaseUrl, {
extensions: { pg_trgm },
debug: opts?.debug,
});
this.kysely = new Kysely<DittoTables>({
dialect: new PgliteDialect({ database: this.pglite }),
log: KyselyLogger,
});
this.migrator = new DittoPgMigrator(this.kysely);
}
listen(channel: string, callback: (payload: string) => void): void {
this.pglite.listen(channel, callback);
}
async migrate(): Promise<void> {
await this.migrator.migrate();
}
async [Symbol.asyncDispose](): Promise<void> {
try {
// FIXME: `kysely.destroy()` calls `pglite.close()` internally, but it doesn't work.
await this.pglite.close();
await this.kysely.destroy();
} catch (e) {
if (e instanceof Error && e.message === 'PGlite is closed') {
// Make dispose idempotent.
} else {
throw e;
}
}
}
}

View file

@ -0,0 +1,6 @@
import { DittoPolyPg } from './DittoPolyPg.ts';
Deno.test('DittoPolyPg', async () => {
const db = new DittoPolyPg('memory://');
await db.migrate();
});

View file

@ -0,0 +1,53 @@
import { DittoPglite } from './DittoPglite.ts';
import { DittoPostgres } from './DittoPostgres.ts';
import type { Kysely } from 'kysely';
import type { DittoDB, DittoDBOpts } from '../DittoDB.ts';
import type { DittoTables } from '../DittoTables.ts';
/** Creates either a PGlite or Postgres connection depending on the databaseUrl. */
export class DittoPolyPg implements DittoDB {
private adapter: DittoDB;
/** Open a new database connection. */
constructor(databaseUrl: string, opts?: DittoDBOpts) {
const { protocol } = new URL(databaseUrl);
switch (protocol) {
case 'file:':
case 'memory:':
this.adapter = new DittoPglite(databaseUrl, opts);
break;
case 'postgres:':
case 'postgresql:':
this.adapter = new DittoPostgres(databaseUrl, opts);
break;
default:
throw new Error('Unsupported database URL.');
}
}
get kysely(): Kysely<DittoTables> {
return this.adapter.kysely;
}
async migrate(): Promise<void> {
await this.adapter.migrate();
}
listen(channel: string, callback: (payload: string) => void): void {
this.adapter.listen(channel, callback);
}
get poolSize(): number {
return this.adapter.poolSize;
}
get availableConnections(): number {
return this.adapter.availableConnections;
}
async [Symbol.asyncDispose](): Promise<void> {
await this.adapter[Symbol.asyncDispose]();
}
}

View file

@ -0,0 +1,22 @@
import { DittoConf } from '@ditto/conf';
import { DittoPostgres } from './DittoPostgres.ts';
const conf = new DittoConf(Deno.env);
const isPostgres = /^postgres(?:ql)?:/.test(conf.databaseUrl);
Deno.test('DittoPostgres', { ignore: !isPostgres }, async () => {
await using db = new DittoPostgres(conf.databaseUrl);
await db.migrate();
});
// FIXME: There is a problem with postgres-js where queries just hang after the database is closed.
// Deno.test('DittoPostgres query after closing', { ignore: !isPostgres }, async () => {
// const db = new DittoPostgres(conf.databaseUrl);
// await db[Symbol.asyncDispose]();
//
// await assertRejects(
// () => db.kysely.selectFrom('nostr_events').selectAll().execute(),
// );
// });

View file

@ -0,0 +1,79 @@
import {
type BinaryOperationNode,
FunctionNode,
Kysely,
OperatorNode,
PostgresAdapter,
PostgresIntrospector,
PostgresQueryCompiler,
PrimitiveValueListNode,
ValueNode,
} from 'kysely';
import { type PostgresJSDialectConfig, PostgresJSDriver } from 'kysely-postgres-js';
import postgres from 'postgres';
import { DittoPgMigrator } from '../DittoPgMigrator.ts';
import { KyselyLogger } from '../KyselyLogger.ts';
import type { DittoDB, DittoDBOpts } from '../DittoDB.ts';
import type { DittoTables } from '../DittoTables.ts';
export class DittoPostgres implements DittoDB {
private pg: ReturnType<typeof postgres>;
private migrator: DittoPgMigrator;
readonly kysely: Kysely<DittoTables>;
constructor(databaseUrl: string, opts?: DittoDBOpts) {
this.pg = postgres(databaseUrl, { max: opts?.poolSize });
this.kysely = new Kysely<DittoTables>({
dialect: {
createAdapter: () => new PostgresAdapter(),
createDriver: () =>
new PostgresJSDriver({ postgres: this.pg as unknown as PostgresJSDialectConfig['postgres'] }),
createIntrospector: (db) => new PostgresIntrospector(db),
createQueryCompiler: () => new DittoPostgresQueryCompiler(),
},
log: KyselyLogger,
});
this.migrator = new DittoPgMigrator(this.kysely);
}
listen(channel: string, callback: (payload: string) => void): void {
this.pg.listen(channel, callback);
}
async migrate(): Promise<void> {
await this.migrator.migrate();
}
get poolSize(): number {
return this.pg.connections.open;
}
get availableConnections(): number {
return this.pg.connections.idle;
}
async [Symbol.asyncDispose](): Promise<void> {
await this.pg.end({ timeout: 0 }); // force-close the connections
await this.kysely.destroy();
}
}
/** Converts `in` queries to `any` to improve prepared statements on Postgres. */
class DittoPostgresQueryCompiler extends PostgresQueryCompiler {
protected override visitBinaryOperation(node: BinaryOperationNode): void {
if (
OperatorNode.is(node.operator) && node.operator.operator === 'in' && PrimitiveValueListNode.is(node.rightOperand)
) {
this.visitNode(node.leftOperand);
this.append(' = ');
this.visitNode(FunctionNode.create('any', [ValueNode.create(node.rightOperand.values)]));
} else {
super.visitBinaryOperation(node);
}
}
}

View file

@ -0,0 +1,11 @@
import { assertEquals } from '@std/assert';
import { DummyDB } from './DummyDB.ts';
Deno.test('DummyDB', async () => {
const db = new DummyDB();
await db.migrate();
const rows = await db.kysely.selectFrom('nostr_events').selectAll().execute();
assertEquals(rows, []);
});

View file

@ -0,0 +1,33 @@
import { DummyDriver, Kysely, PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler } from 'kysely';
import type { DittoDB } from '../DittoDB.ts';
import type { DittoTables } from '../DittoTables.ts';
export class DummyDB implements DittoDB {
readonly kysely: Kysely<DittoTables>;
readonly poolSize = 0;
readonly availableConnections = 0;
constructor() {
this.kysely = new Kysely<DittoTables>({
dialect: {
createAdapter: () => new PostgresAdapter(),
createDriver: () => new DummyDriver(),
createIntrospector: (db) => new PostgresIntrospector(db),
createQueryCompiler: () => new PostgresQueryCompiler(),
},
});
}
listen(): void {
// noop
}
migrate(): Promise<void> {
return Promise.resolve();
}
[Symbol.asyncDispose](): Promise<void> {
return Promise.resolve();
}
}

View file

@ -0,0 +1,25 @@
import { DittoConf } from '@ditto/conf';
import { NPostgres } from '@nostrify/db';
import { genEvent } from '@nostrify/nostrify/test';
import { assertEquals } from '@std/assert';
import { DittoPolyPg } from './DittoPolyPg.ts';
import { TestDB } from './TestDB.ts';
Deno.test('TestDB', async () => {
const conf = new DittoConf(Deno.env);
const orig = new DittoPolyPg(conf.databaseUrl);
await using db = new TestDB(orig);
await db.migrate();
await db.clear();
const store = new NPostgres(orig.kysely);
await store.event(genEvent());
assertEquals((await store.count([{}])).count, 1);
await db.clear();
assertEquals((await store.count([{}])).count, 0);
});

View file

@ -0,0 +1,49 @@
import { type Kysely, sql } from 'kysely';
import type { DittoDB } from '../DittoDB.ts';
import type { DittoTables } from '../DittoTables.ts';
/** Wraps another DittoDB implementation to clear all data when disposed. */
export class TestDB implements DittoDB {
constructor(private db: DittoDB) {}
get kysely(): Kysely<DittoTables> {
return this.db.kysely;
}
get poolSize(): number {
return this.db.poolSize;
}
get availableConnections(): number {
return this.db.availableConnections;
}
migrate(): Promise<void> {
return this.db.migrate();
}
listen(channel: string, callback: (payload: string) => void): void {
return this.db.listen(channel, callback);
}
/** Truncate all tables. */
async clear(): Promise<void> {
const query = sql<{ tablename: string }>`select tablename from pg_tables where schemaname = current_schema()`;
const { rows } = await query.execute(this.db.kysely);
for (const { tablename } of rows) {
if (tablename.startsWith('kysely_')) {
continue; // Skip Kysely's internal tables
} else {
await sql`truncate table ${sql.ref(tablename)} cascade`.execute(this.db.kysely);
}
}
}
async [Symbol.asyncDispose](): Promise<void> {
await this.clear();
await this.db[Symbol.asyncDispose]();
}
}

7
packages/db/deno.json Normal file
View file

@ -0,0 +1,7 @@
{
"name": "@ditto/db",
"version": "0.1.0",
"exports": {
".": "./mod.ts"
}
}

View file

@ -1,6 +1,6 @@
import { Kysely } from 'kysely'; import type { Kysely } from 'kysely';
export async function up(db: Kysely<any>): Promise<void> { export async function up(db: Kysely<unknown>): Promise<void> {
await db.schema await db.schema
.createTable('events') .createTable('events')
.addColumn('id', 'text', (col) => col.primaryKey()) .addColumn('id', 'text', (col) => col.primaryKey())
@ -52,7 +52,7 @@ export async function up(db: Kysely<any>): Promise<void> {
.execute(); .execute();
} }
export async function down(db: Kysely<any>): Promise<void> { export async function down(db: Kysely<unknown>): Promise<void> {
await db.schema.dropTable('events').execute(); await db.schema.dropTable('events').execute();
await db.schema.dropTable('tags').execute(); await db.schema.dropTable('tags').execute();
await db.schema.dropTable('users').execute(); await db.schema.dropTable('users').execute();

View file

@ -1,6 +1,6 @@
import { Kysely } from 'kysely'; import type { Kysely } from 'kysely';
export async function up(db: Kysely<any>): Promise<void> { export async function up(db: Kysely<unknown>): Promise<void> {
await db.schema await db.schema
.createTable('relays') .createTable('relays')
.addColumn('url', 'text', (col) => col.primaryKey()) .addColumn('url', 'text', (col) => col.primaryKey())
@ -9,6 +9,6 @@ export async function up(db: Kysely<any>): Promise<void> {
.execute(); .execute();
} }
export async function down(db: Kysely<any>): Promise<void> { export async function down(db: Kysely<unknown>): Promise<void> {
await db.schema.dropTable('relays').execute(); await db.schema.dropTable('relays').execute();
} }

View file

@ -0,0 +1,8 @@
import type { Kysely } from 'kysely';
export async function up(_db: Kysely<unknown>): Promise<void> {
// This migration used to create an FTS table for SQLite, but SQLite support was removed.
}
export async function down(_db: Kysely<unknown>): Promise<void> {
}

View file

@ -0,0 +1,8 @@
import type { Kysely } from 'kysely';
export async function up(_db: Kysely<unknown>): Promise<void> {
}
export async function down(db: Kysely<unknown>): Promise<void> {
await db.schema.alterTable('users').dropColumn('admin').execute();
}

View file

@ -0,0 +1,9 @@
import type { Kysely } from 'kysely';
export async function up(_db: Kysely<unknown>): Promise<void> {
}
export async function down(db: Kysely<unknown>): Promise<void> {
await db.schema.dropIndex('idx_users_pubkey').execute();
await db.schema.dropIndex('idx_users_username').execute();
}

View file

@ -1,6 +1,6 @@
import { Kysely, sql } from 'kysely'; import { type Kysely, sql } from 'kysely';
export async function up(db: Kysely<any>): Promise<void> { export async function up(db: Kysely<unknown>): Promise<void> {
await db.schema await db.schema
.createTable('tags_new') .createTable('tags_new')
.addColumn('tag', 'text', (col) => col.notNull()) .addColumn('tag', 'text', (col) => col.notNull())
@ -42,7 +42,7 @@ export async function up(db: Kysely<any>): Promise<void> {
.execute(); .execute();
} }
export async function down(db: Kysely<any>): Promise<void> { export async function down(db: Kysely<unknown>): Promise<void> {
await db.schema.dropTable('tags').execute(); await db.schema.dropTable('tags').execute();
await db.schema await db.schema

View file

@ -0,0 +1,7 @@
import type { Kysely } from 'kysely';
export async function up(_db: Kysely<unknown>): Promise<void> {
}
export async function down(_db: Kysely<unknown>): Promise<void> {
}

View file

@ -1,6 +1,6 @@
import { Kysely } from 'kysely'; import type { Kysely } from 'kysely';
export async function up(db: Kysely<any>): Promise<void> { export async function up(db: Kysely<unknown>): Promise<void> {
await db.schema await db.schema
.createTable('unattached_media') .createTable('unattached_media')
.addColumn('id', 'text', (c) => c.primaryKey()) .addColumn('id', 'text', (c) => c.primaryKey())
@ -29,6 +29,6 @@ export async function up(db: Kysely<any>): Promise<void> {
.execute(); .execute();
} }
export async function down(db: Kysely<any>): Promise<void> { export async function down(db: Kysely<unknown>): Promise<void> {
await db.schema.dropTable('unattached_media').execute(); await db.schema.dropTable('unattached_media').execute();
} }

View file

@ -0,0 +1,7 @@
import type { Kysely } from 'kysely';
export async function up(_db: Kysely<unknown>): Promise<void> {
}
export async function down(_db: Kysely<unknown>): Promise<void> {
}

View file

@ -1,6 +1,6 @@
import { Kysely } from 'kysely'; import type { Kysely } from 'kysely';
export async function up(db: Kysely<any>): Promise<void> { export async function up(db: Kysely<unknown>): Promise<void> {
await db.schema await db.schema
.createTable('author_stats') .createTable('author_stats')
.addColumn('pubkey', 'text', (col) => col.primaryKey()) .addColumn('pubkey', 'text', (col) => col.primaryKey())
@ -18,7 +18,7 @@ export async function up(db: Kysely<any>): Promise<void> {
.execute(); .execute();
} }
export async function down(db: Kysely<any>): Promise<void> { export async function down(db: Kysely<unknown>): Promise<void> {
await db.schema.dropTable('author_stats').execute(); await db.schema.dropTable('author_stats').execute();
await db.schema.dropTable('event_stats').execute(); await db.schema.dropTable('event_stats').execute();
} }

View file

@ -0,0 +1,8 @@
import type { Kysely } from 'kysely';
export async function up(db: Kysely<unknown>): Promise<void> {
await db.schema.dropTable('users').ifExists().execute();
}
export async function down(_db: Kysely<unknown>): Promise<void> {
}

View file

@ -1,6 +1,6 @@
import { Kysely } from 'kysely'; import type { Kysely } from 'kysely';
export async function up(db: Kysely<any>): Promise<void> { export async function up(db: Kysely<unknown>): Promise<void> {
await db.schema await db.schema
.createIndex('idx_events_kind_pubkey_created_at') .createIndex('idx_events_kind_pubkey_created_at')
.on('events') .on('events')
@ -8,6 +8,6 @@ export async function up(db: Kysely<any>): Promise<void> {
.execute(); .execute();
} }
export async function down(db: Kysely<any>): Promise<void> { export async function down(db: Kysely<unknown>): Promise<void> {
await db.schema.dropIndex('idx_events_kind_pubkey_created_at').execute(); await db.schema.dropIndex('idx_events_kind_pubkey_created_at').execute();
} }

Some files were not shown because too many files have changed in this diff Show more