Remove username from user events

This commit is contained in:
Alex Gleason 2024-03-27 18:10:04 -05:00
parent 8baa9a16db
commit 9842b1aedd
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
3 changed files with 13 additions and 51 deletions

View File

@ -2,29 +2,6 @@
Instead of using database tables, the Ditto server publishes Nostr events that describe its state. It then reads these events using Nostr filters. Instead of using database tables, the Ditto server publishes Nostr events that describe its state. It then reads these events using Nostr filters.
## Ditto Registration Request (kind 3036)
Clients wishing to join a Ditto server should publish a kind `3036` event to the Ditto relay, mentioning the Ditto admin pubkey.
The event should have the following tags:
- `nip05` - desired NIP-05 username, including the domain (eg `alex@soapbox.pub`).
- `p` - pubkey of the Ditto admin.
Example:
```json
{
"kind": 3036,
"pubkey": "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6",
"content": "I want to be a part of this community.",
"tags": [
["nip05", "alex@soapbox.pub"],
["p", "4cfc6ceb07bbe2f5e75f746f3e6f0eda53973e0374cd6bdbce7a930e10437e06"]
]
}
```
## Ditto User (kind 30361) ## Ditto User (kind 30361)
The Ditto server publishes kind `30361` events to represent users. These events are parameterized replaceable events of kind `30361` where the `d` tag is a pubkey. These events are published by Ditto's internal admin keypair. The Ditto server publishes kind `30361` events to represent users. These events are parameterized replaceable events of kind `30361` where the `d` tag is a pubkey. These events are published by Ditto's internal admin keypair.
@ -47,10 +24,9 @@ Example:
"created_at": 1691568245, "created_at": 1691568245,
"tags": [ "tags": [
["d", "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6"], ["d", "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6"],
["name", "alex"],
["role", "user"], ["role", "user"],
["origin", "https://ditto.ngrok.app"], ["origin", "https://ditto.ngrok.app"],
["alt", "@alex@ditto.ngrok.app's account was updated by the admins of ditto.ngrok.app"] ["alt", "User's account was updated by the admins of ditto.ngrok.app"]
], ],
"sig": "fc12db77b1c8f8aa86c73b617f0cd4af1e6ba244239eaf3164a292de6d39363f32d6b817ffff796ace7a103d75e1d8e6a0fb7f618819b32d81a953b4a75d7507" "sig": "fc12db77b1c8f8aa86c73b617f0cd4af1e6ba244239eaf3164a292de6d39363f32d6b817ffff796ace7a103d75e1d8e6a0fb7f618819b32d81a953b4a75d7507"
} }

View File

@ -39,10 +39,8 @@ const createAccountController: AppController = async (c) => {
return c.json({ error: 'Bad request', schema: result.error }, 400); return c.json({ error: 'Bad request', schema: result.error }, 400);
} }
try {
await insertUser({ await insertUser({
pubkey, pubkey,
username: result.data.username,
inserted_at: new Date(), inserted_at: new Date(),
admin: false, admin: false,
}); });
@ -53,9 +51,6 @@ const createAccountController: AppController = async (c) => {
scope: 'read write follow push', scope: 'read write follow push',
created_at: nostrNow(), created_at: nostrNow(),
}); });
} catch (_e) {
return c.json({ error: 'Username already taken.' }, 422);
}
}; };
const verifyCredentialsController: AppController = async (c) => { const verifyCredentialsController: AppController = async (c) => {

View File

@ -8,7 +8,6 @@ const debug = Debug('ditto:users');
interface User { interface User {
pubkey: string; pubkey: string;
username: string;
inserted_at: Date; inserted_at: Date;
admin: boolean; admin: boolean;
} }
@ -21,11 +20,10 @@ function buildUserEvent(user: User) {
kind: 30361, kind: 30361,
tags: [ tags: [
['d', user.pubkey], ['d', user.pubkey],
['name', user.username],
['role', user.admin ? 'admin' : 'user'], ['role', user.admin ? 'admin' : 'user'],
['origin', origin], ['origin', origin],
// NIP-31: https://github.com/nostr-protocol/nips/blob/master/31.md // NIP-31: https://github.com/nostr-protocol/nips/blob/master/31.md
['alt', `@${user.username}@${host}'s account was updated by the admins of ${host}`], ['alt', `User's account was updated by the admins of ${host}`],
], ],
content: '', content: '',
created_at: Math.floor(user.inserted_at.getTime() / 1000), created_at: Math.floor(user.inserted_at.getTime() / 1000),
@ -35,9 +33,6 @@ function buildUserEvent(user: User) {
/** Adds a user to the database. */ /** Adds a user to the database. */
async function insertUser(user: User) { async function insertUser(user: User) {
debug('insertUser', JSON.stringify(user)); debug('insertUser', JSON.stringify(user));
if (await findUser({ username: user.username })) {
throw new Error('User already exists');
}
const event = await buildUserEvent(user); const event = await buildUserEvent(user);
return pipeline.handleEvent(event, AbortSignal.timeout(1000)); return pipeline.handleEvent(event, AbortSignal.timeout(1000));
} }
@ -57,9 +52,6 @@ async function findUser(user: Partial<User>, signal?: AbortSignal): Promise<User
case 'pubkey': case 'pubkey':
filter['#d'] = [String(value)]; filter['#d'] = [String(value)];
break; break;
case 'username':
filter['#name'] = [String(value)];
break;
case 'admin': case 'admin':
filter['#role'] = [value ? 'admin' : 'user']; filter['#role'] = [value ? 'admin' : 'user'];
break; break;
@ -71,7 +63,6 @@ async function findUser(user: Partial<User>, signal?: AbortSignal): Promise<User
if (event) { if (event) {
return { return {
pubkey: event.tags.find(([name]) => name === 'd')?.[1]!, pubkey: event.tags.find(([name]) => name === 'd')?.[1]!,
username: event.tags.find(([name]) => name === 'name')?.[1]!,
inserted_at: new Date(event.created_at * 1000), inserted_at: new Date(event.created_at * 1000),
admin: event.tags.find(([name]) => name === 'role')?.[1] === 'admin', admin: event.tags.find(([name]) => name === 'role')?.[1] === 'admin',
}; };