From 7b864482bfb687e0b6e8e7c216cc3032145cabbc Mon Sep 17 00:00:00 2001 From: "P. Reis" Date: Sat, 27 Apr 2024 17:00:03 -0300 Subject: [PATCH 1/5] feat: create user store middleware --- src/middleware/userStore.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/middleware/userStore.ts diff --git a/src/middleware/userStore.ts b/src/middleware/userStore.ts new file mode 100644 index 00000000..bd3a4029 --- /dev/null +++ b/src/middleware/userStore.ts @@ -0,0 +1,22 @@ +import { AppMiddleware } from '@/app.ts'; +import { UserStore } from '@/storages/UserStore.ts'; +import { eventsDB } from '@/storages.ts'; +import { HTTPException } from 'hono'; + +/** User Store middleware. + * Throw a 500 if can't set the `userStore` */ +const setUserStore: AppMiddleware = async (c, next) => { + const pubkey = c.get('pubkey') as string; + + try { + const store = new UserStore(pubkey, eventsDB); + c.set('userStore', store); + } catch (e) { + console.log(e); + throw new HTTPException(500); + } + + await next(); +}; + +export { setUserStore }; From 18508d37f2dad8ed4d7f1235c511e6c1bb08e0dd Mon Sep 17 00:00:00 2001 From: "P. Reis" Date: Sat, 27 Apr 2024 17:02:07 -0300 Subject: [PATCH 2/5] feat: define userStore in HonoEnv & set userStore middleware in home timeline --- src/app.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app.ts b/src/app.ts index 68306e53..30abc797 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,4 +1,4 @@ -import { NostrEvent } from '@nostrify/nostrify'; +import { NostrEvent, NStore } from '@nostrify/nostrify'; import { type Context, Env as HonoEnv, type Handler, Hono, Input as HonoInput, type MiddlewareHandler } from 'hono'; import { cors, logger, serveStatic } from 'hono/middleware'; @@ -78,6 +78,7 @@ import { auth98, requireProof, requireRole } from '@/middleware/auth98.ts'; import { cache } from '@/middleware/cache.ts'; import { csp } from '@/middleware/csp.ts'; import { adminRelaysController } from '@/controllers/api/ditto.ts'; +import { setUserStore } from '@/middleware/userStore.ts'; interface AppEnv extends HonoEnv { Variables: { @@ -89,6 +90,8 @@ interface AppEnv extends HonoEnv { proof?: NostrEvent; /** User associated with the pubkey, if any. */ user?: User; + /** User Store (pubkey has to be set to use it). */ + userStore?: NStore; }; } @@ -170,7 +173,7 @@ app.delete('/api/v1/statuses/:id{[0-9a-f]{64}}', requirePubkey, deleteStatusCont app.post('/api/v1/media', mediaController); app.post('/api/v2/media', mediaController); -app.get('/api/v1/timelines/home', requirePubkey, homeTimelineController); +app.get('/api/v1/timelines/home', requirePubkey, setUserStore, homeTimelineController); app.get('/api/v1/timelines/public', publicTimelineController); app.get('/api/v1/timelines/tag/:hashtag', hashtagTimelineController); From a7912e08007e42bf672eacfdcc82a78b97fee141 Mon Sep 17 00:00:00 2001 From: "P. Reis" Date: Sat, 27 Apr 2024 17:03:30 -0300 Subject: [PATCH 3/5] feat: if possible use userStore in renderStatuses() --- src/controllers/api/timelines.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/controllers/api/timelines.ts b/src/controllers/api/timelines.ts index 5e7bab6c..0903062c 100644 --- a/src/controllers/api/timelines.ts +++ b/src/controllers/api/timelines.ts @@ -1,4 +1,4 @@ -import { NostrFilter } from '@nostrify/nostrify'; +import { NostrFilter, NStore } from '@nostrify/nostrify'; import { z } from 'zod'; import { type AppContext, type AppController } from '@/app.ts'; @@ -46,13 +46,17 @@ const hashtagTimelineController: AppController = (c) => { /** Render statuses for timelines. */ async function renderStatuses(c: AppContext, filters: NostrFilter[]) { const { signal } = c.req.raw; + const userStore = c.get('userStore'); - const events = await eventsDB + let store: NStore = eventsDB; + if (userStore) store = userStore; + + const events = await store .query(filters, { signal }) .then((events) => hydrateEvents({ events, - storage: eventsDB, + storage: store, signal, }) ); From ab7a60c6ded32b3a14dc7825f173054678297543 Mon Sep 17 00:00:00 2001 From: "P. Reis" Date: Sat, 27 Apr 2024 17:04:14 -0300 Subject: [PATCH 4/5] fix(UserStore): add missing return keyword in array filter --- src/storages/UserStore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storages/UserStore.ts b/src/storages/UserStore.ts index 615e2afd..78c3d336 100644 --- a/src/storages/UserStore.ts +++ b/src/storages/UserStore.ts @@ -29,7 +29,7 @@ export class UserStore implements NStore { const mutedPubkeys = getTagSet(mutedPubkeysEvent.tags, 'p'); return allEvents.filter((event) => { - mutedPubkeys.has(event.pubkey) === false; + return mutedPubkeys.has(event.pubkey) === false; }); } From 86573a579bf69ce74e1c621c7531f0af3790c52d Mon Sep 17 00:00:00 2001 From: "P. Reis" Date: Sat, 27 Apr 2024 20:59:35 -0300 Subject: [PATCH 5/5] refactor: store middleware --- src/app.ts | 10 +++++----- src/controllers/api/timelines.ts | 6 +----- src/middleware/store.ts | 18 ++++++++++++++++++ src/middleware/userStore.ts | 22 ---------------------- 4 files changed, 24 insertions(+), 32 deletions(-) create mode 100644 src/middleware/store.ts delete mode 100644 src/middleware/userStore.ts diff --git a/src/app.ts b/src/app.ts index 30abc797..abdec32a 100644 --- a/src/app.ts +++ b/src/app.ts @@ -78,7 +78,7 @@ import { auth98, requireProof, requireRole } from '@/middleware/auth98.ts'; import { cache } from '@/middleware/cache.ts'; import { csp } from '@/middleware/csp.ts'; import { adminRelaysController } from '@/controllers/api/ditto.ts'; -import { setUserStore } from '@/middleware/userStore.ts'; +import { storeMiddleware } from '@/middleware/store.ts'; interface AppEnv extends HonoEnv { Variables: { @@ -90,8 +90,8 @@ interface AppEnv extends HonoEnv { proof?: NostrEvent; /** User associated with the pubkey, if any. */ user?: User; - /** User Store (pubkey has to be set to use it). */ - userStore?: NStore; + /** Store */ + store?: NStore; }; } @@ -173,8 +173,8 @@ app.delete('/api/v1/statuses/:id{[0-9a-f]{64}}', requirePubkey, deleteStatusCont app.post('/api/v1/media', mediaController); app.post('/api/v2/media', mediaController); -app.get('/api/v1/timelines/home', requirePubkey, setUserStore, homeTimelineController); -app.get('/api/v1/timelines/public', publicTimelineController); +app.get('/api/v1/timelines/home', requirePubkey, storeMiddleware, homeTimelineController); +app.get('/api/v1/timelines/public', storeMiddleware, publicTimelineController); app.get('/api/v1/timelines/tag/:hashtag', hashtagTimelineController); app.get('/api/v1/preferences', preferencesController); diff --git a/src/controllers/api/timelines.ts b/src/controllers/api/timelines.ts index 0903062c..191fce74 100644 --- a/src/controllers/api/timelines.ts +++ b/src/controllers/api/timelines.ts @@ -5,7 +5,6 @@ import { type AppContext, type AppController } from '@/app.ts'; import { Conf } from '@/config.ts'; import { getFeedPubkeys } from '@/queries.ts'; import { booleanParamSchema } from '@/schema.ts'; -import { eventsDB } from '@/storages.ts'; import { hydrateEvents } from '@/storages/hydrate.ts'; import { paginated, paginationSchema } from '@/utils/api.ts'; import { renderReblog, renderStatus } from '@/views/mastodon/statuses.ts'; @@ -46,10 +45,7 @@ const hashtagTimelineController: AppController = (c) => { /** Render statuses for timelines. */ async function renderStatuses(c: AppContext, filters: NostrFilter[]) { const { signal } = c.req.raw; - const userStore = c.get('userStore'); - - let store: NStore = eventsDB; - if (userStore) store = userStore; + const store = c.get('store') as NStore; const events = await store .query(filters, { signal }) diff --git a/src/middleware/store.ts b/src/middleware/store.ts new file mode 100644 index 00000000..8bb595cb --- /dev/null +++ b/src/middleware/store.ts @@ -0,0 +1,18 @@ +import { AppMiddleware } from '@/app.ts'; +import { UserStore } from '@/storages/UserStore.ts'; +import { eventsDB } from '@/storages.ts'; + +/** Store middleware. */ +const storeMiddleware: AppMiddleware = async (c, next) => { + const pubkey = c.get('pubkey') as string; + + if (pubkey) { + const store = new UserStore(pubkey, eventsDB); + c.set('store', store); + } else { + c.set('store', eventsDB); + } + await next(); +}; + +export { storeMiddleware }; diff --git a/src/middleware/userStore.ts b/src/middleware/userStore.ts deleted file mode 100644 index bd3a4029..00000000 --- a/src/middleware/userStore.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AppMiddleware } from '@/app.ts'; -import { UserStore } from '@/storages/UserStore.ts'; -import { eventsDB } from '@/storages.ts'; -import { HTTPException } from 'hono'; - -/** User Store middleware. - * Throw a 500 if can't set the `userStore` */ -const setUserStore: AppMiddleware = async (c, next) => { - const pubkey = c.get('pubkey') as string; - - try { - const store = new UserStore(pubkey, eventsDB); - c.set('userStore', store); - } catch (e) { - console.log(e); - throw new HTTPException(500); - } - - await next(); -}; - -export { setUserStore };