Remove username from user events
This commit is contained in:
parent
8baa9a16db
commit
9842b1aedd
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,23 +39,18 @@ 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,
|
inserted_at: new Date(),
|
||||||
username: result.data.username,
|
admin: false,
|
||||||
inserted_at: new Date(),
|
});
|
||||||
admin: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
return c.json({
|
return c.json({
|
||||||
access_token: nip19.npubEncode(pubkey),
|
access_token: nip19.npubEncode(pubkey),
|
||||||
token_type: 'Bearer',
|
token_type: 'Bearer',
|
||||||
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) => {
|
||||||
|
|
|
@ -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',
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue