Simple Authorization (#477)

This commit is contained in:
Water Blowater 2024-06-06 18:36:57 +08:00 committed by GitHub
parent e0009aeee9
commit e94a40eaf6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 18 additions and 107 deletions

View File

@ -1,50 +0,0 @@
import { DB } from "https://deno.land/x/sqlite@v3.7.2/mod.ts";
import { NostrKind } from "../libs/nostr.ts/nostr.ts";
import { ConnectionPool } from "../libs/nostr.ts/relay-pool.ts";
// Open a database
const db = new DB("stats.sqlite");
db.execute(`
CREATE TABLE IF NOT EXISTS stats (
pubkey TEXT,
eventID TEXT,
PRIMARY KEY (pubkey, eventID)
)
`);
const pool = new ConnectionPool();
const urls = [
"wss://relay.damus.io",
"wss://nos.lol",
"wss://eden.nostr.land",
"wss://brb.io",
"wss://sg.qemura.xyz",
"wss://nostr-sg.com",
"wss://nostr-pub.wellorder.net",
"wss://relay.snort.social",
"wss://offchain.pub",
];
for (const url of urls) {
pool.addRelayURL(url);
}
const r = await pool.newSub("stats", {
kinds: [NostrKind.Custom_App_Data],
});
if (r instanceof Error) {
throw r;
}
for await (const { res: e, url } of r.chan) {
console.log(url);
if (e.type != "EVENT") {
continue;
}
const pub = e.event.pubkey;
try {
db.query("INSERT INTO stats (pubkey, eventID) VALUES (?, ?)", [pub, e.event.id]);
} catch (e) {
console.log(e.message);
}
}

View File

@ -1,10 +0,0 @@
import { DB } from "https://deno.land/x/sqlite@v3.7.2/mod.ts";
const query = `SELECT DISTINCT(pubkey) From stats`;
const db = new DB("stats.sqlite");
const res = db.query(query);
for (const row of res) {
console.log(row);
}
console.log(res.length, "keys");

View File

@ -51,21 +51,10 @@ export async function Start(database: DexieDatabase) {
const lamport = new LamportTime(); const lamport = new LamportTime();
const model = initialModel(); const model = initialModel();
const eventBus = new EventBus<UI_Interaction_Event>(); const eventBus = new EventBus<UI_Interaction_Event>();
const pool = new ConnectionPool();
const popOverInputChan: PopOverInputChannel = new Channel(); const popOverInputChan: PopOverInputChannel = new Channel();
const rightPanelInputChan: RightPanelChannel = new Channel(); const rightPanelInputChan: RightPanelChannel = new Channel();
const toastInputChan: ToastChannel = new Channel(); const toastInputChan: ToastChannel = new Channel();
const dbView = await Database_View.New(database, database, database); const dbView = await Database_View.New(database, database, database);
const newNostrEventChannel = new Channel<NostrEvent>();
(async () => {
for await (const event of newNostrEventChannel) {
const err = await pool.sendEvent(event);
if (err instanceof Error) {
console.error(err);
}
}
})();
{ {
for (;;) { for (;;) {
@ -77,13 +66,13 @@ export async function Start(database: DexieDatabase) {
console.error(ctx); console.error(ctx);
break; break;
} else if (ctx) { } else if (ctx) {
const otherConfig = await OtherConfig.FromLocalStorage(ctx, newNostrEventChannel, lamport); const otherConfig = await OtherConfig.FromLocalStorage(ctx, lamport);
const app = await App.Start({ const app = await App.Start({
database: dbView, database: dbView,
model, model,
ctx, ctx,
eventBus, eventBus,
pool, pool: new ConnectionPool({ signer: ctx }),
popOverInputChan, popOverInputChan,
rightPanelInputChan, rightPanelInputChan,
otherConfig, otherConfig,
@ -101,7 +90,6 @@ export async function Start(database: DexieDatabase) {
<AppComponent <AppComponent
eventBus={eventBus} eventBus={eventBus}
model={model} model={model}
pool={pool}
popOverInputChan={popOverInputChan} popOverInputChan={popOverInputChan}
rightPanelInputChan={rightPanelInputChan} rightPanelInputChan={rightPanelInputChan}
installPrompt={installPrompt} installPrompt={installPrompt}
@ -115,10 +103,8 @@ export async function Start(database: DexieDatabase) {
model, model,
eventBus, eventBus,
dbView: dbView, dbView: dbView,
pool,
popOver: popOverInputChan, popOver: popOverInputChan,
rightPanel: rightPanelInputChan, rightPanel: rightPanelInputChan,
newNostrEventChannel: newNostrEventChannel,
lamport, lamport,
installPrompt, installPrompt,
toastInputChan: toastInputChan, toastInputChan: toastInputChan,
@ -130,7 +116,6 @@ export async function Start(database: DexieDatabase) {
<AppComponent <AppComponent
eventBus={eventBus} eventBus={eventBus}
model={model} model={model}
pool={pool}
popOverInputChan={popOverInputChan} popOverInputChan={popOverInputChan}
rightPanelInputChan={rightPanelInputChan} rightPanelInputChan={rightPanelInputChan}
installPrompt={installPrompt} installPrompt={installPrompt}
@ -287,7 +272,6 @@ export class App {
<AppComponent <AppComponent
eventBus={this.eventBus} eventBus={this.eventBus}
model={this.model} model={this.model}
pool={this.pool}
popOverInputChan={this.popOverInputChan} popOverInputChan={this.popOverInputChan}
rightPanelInputChan={this.rightPanelInputChan} rightPanelInputChan={this.rightPanelInputChan}
installPrompt={installPrompt} installPrompt={installPrompt}
@ -319,7 +303,6 @@ export class App {
<AppComponent <AppComponent
eventBus={this.eventBus} eventBus={this.eventBus}
model={this.model} model={this.model}
pool={this.pool}
popOverInputChan={this.popOverInputChan} popOverInputChan={this.popOverInputChan}
rightPanelInputChan={this.rightPanelInputChan} rightPanelInputChan={this.rightPanelInputChan}
installPrompt={installPrompt} installPrompt={installPrompt}
@ -341,7 +324,6 @@ export class App {
type AppProps = { type AppProps = {
model: Model; model: Model;
eventBus: AppEventBus; eventBus: AppEventBus;
pool: ConnectionPool;
popOverInputChan: PopOverInputChannel; popOverInputChan: PopOverInputChannel;
rightPanelInputChan: RightPanelChannel; rightPanelInputChan: RightPanelChannel;
toastInputChan: ToastChannel; toastInputChan: ToastChannel;
@ -457,7 +439,7 @@ export class AppComponent extends Component<AppProps, {
}, },
), ),
)} )}
relay={props.pool.getRelay(model.currentRelay) as SingleRelayConnection} relay_url={model.currentRelay}
bus={app.eventBus} bus={app.eventBus}
/> />
); );
@ -503,7 +485,7 @@ export class AppComponent extends Component<AppProps, {
logout: app.logout, logout: app.logout,
relayConfig: app.relayConfig, relayConfig: app.relayConfig,
myAccountContext: myAccountCtx, myAccountContext: myAccountCtx,
relayPool: props.pool, relayPool: app.pool,
emit: props.eventBus.emit, emit: props.eventBus.emit,
})} })}
<Popover <Popover

View File

@ -111,10 +111,8 @@ export function UI_Interaction_Update(args: {
model: Model; model: Model;
eventBus: AppEventBus; eventBus: AppEventBus;
dbView: Database_View; dbView: Database_View;
pool: ConnectionPool;
popOver: PopOverInputChannel; popOver: PopOverInputChannel;
rightPanel: RightPanelChannel; rightPanel: RightPanelChannel;
newNostrEventChannel: Channel<NostrEvent>;
lamport: LamportTime; lamport: LamportTime;
installPrompt: InstallPrompt; installPrompt: InstallPrompt;
toastInputChan: ToastChannel; toastInputChan: ToastChannel;
@ -128,15 +126,13 @@ const handle_update_event = async (chan: PutChannel<true>, args: {
model: Model; model: Model;
eventBus: AppEventBus; eventBus: AppEventBus;
dbView: Database_View; dbView: Database_View;
pool: ConnectionPool;
popOver: PopOverInputChannel; popOver: PopOverInputChannel;
rightPanel: RightPanelChannel; rightPanel: RightPanelChannel;
newNostrEventChannel: Channel<NostrEvent>;
lamport: LamportTime; lamport: LamportTime;
installPrompt: InstallPrompt; installPrompt: InstallPrompt;
toastInputChan: ToastChannel; toastInputChan: ToastChannel;
}) => { }) => {
const { model, dbView, eventBus, pool, installPrompt } = args; const { model, dbView, eventBus, installPrompt } = args;
for await (const event of eventBus.onChange()) { for await (const event of eventBus.onChange()) {
console.log(event); console.log(event);
if (event.type == "SignInEvent") { if (event.type == "SignInEvent") {
@ -144,7 +140,6 @@ const handle_update_event = async (chan: PutChannel<true>, args: {
console.log("sign in as", ctx.publicKey.bech32()); console.log("sign in as", ctx.publicKey.bech32());
const otherConfig = await OtherConfig.FromLocalStorage( const otherConfig = await OtherConfig.FromLocalStorage(
ctx, ctx,
args.newNostrEventChannel,
args.lamport, args.lamport,
); );
const app = await App.Start({ const app = await App.Start({
@ -152,7 +147,7 @@ const handle_update_event = async (chan: PutChannel<true>, args: {
model, model,
ctx, ctx,
eventBus, eventBus,
pool, pool: new ConnectionPool({ signer: ctx }),
popOverInputChan: args.popOver, popOverInputChan: args.popOver,
rightPanelInputChan: args.rightPanel, rightPanelInputChan: args.rightPanel,
otherConfig, otherConfig,
@ -170,7 +165,7 @@ const handle_update_event = async (chan: PutChannel<true>, args: {
console.warn("This could not happen!"); console.warn("This could not happen!");
continue; continue;
} }
const pool = app.pool;
const blowater_relay = pool.getRelay(default_blowater_relay); const blowater_relay = pool.getRelay(default_blowater_relay);
if (blowater_relay == undefined) { if (blowater_relay == undefined) {
console.error(Array.from(pool.getRelays())); console.error(Array.from(pool.getRelays()));

View File

@ -11,27 +11,26 @@ export type NostrEventAdder = {
}; };
export class OtherConfig implements PinListGetter, NostrEventAdder { export class OtherConfig implements PinListGetter, NostrEventAdder {
static Empty(nostrEventPusher: Channel<NostrEvent>, ctx: NostrAccountContext, lamport: LamportTime) { static Empty(ctx: NostrAccountContext, lamport: LamportTime) {
return new OtherConfig(nostrEventPusher, ctx, lamport); return new OtherConfig(ctx, lamport);
} }
static async FromLocalStorage( static async FromLocalStorage(
ctx: NostrAccountContext, ctx: NostrAccountContext,
eventPusher: Channel<NostrEvent>,
lamport: LamportTime, lamport: LamportTime,
) { ) {
const item = localStorage.getItem(`${OtherConfig.name}:${ctx.publicKey.bech32()}`); const item = localStorage.getItem(`${OtherConfig.name}:${ctx.publicKey.bech32()}`);
if (item == null) { if (item == null) {
return OtherConfig.Empty(eventPusher, ctx, lamport); return OtherConfig.Empty(ctx, lamport);
} }
const event = parseJSON<NostrEvent>(item); const event = parseJSON<NostrEvent>(item);
if (event instanceof Error) { if (event instanceof Error) {
console.error(event); console.error(event);
return OtherConfig.Empty(eventPusher, ctx, lamport); return OtherConfig.Empty(ctx, lamport);
} }
const ok = await verifyEvent(event); const ok = await verifyEvent(event);
if (!ok) { if (!ok) {
return OtherConfig.Empty(eventPusher, ctx, lamport); return OtherConfig.Empty(ctx, lamport);
} }
if (event.kind == NostrKind.Encrypted_Custom_App_Data) { if (event.kind == NostrKind.Encrypted_Custom_App_Data) {
const config = await OtherConfig.FromNostrEvent( const config = await OtherConfig.FromNostrEvent(
@ -40,19 +39,17 @@ export class OtherConfig implements PinListGetter, NostrEventAdder {
kind: event.kind, kind: event.kind,
}, },
ctx, ctx,
eventPusher,
lamport, lamport,
); );
if (config instanceof Error) { if (config instanceof Error) {
return OtherConfig.Empty(eventPusher, ctx, lamport); return OtherConfig.Empty(ctx, lamport);
} }
return config; return config;
} }
return OtherConfig.Empty(eventPusher, ctx, lamport); return OtherConfig.Empty(ctx, lamport);
} }
private constructor( private constructor(
private readonly nostrEventPusher: Channel<NostrEvent>,
private readonly ctx: NostrAccountContext, private readonly ctx: NostrAccountContext,
private readonly lamport: LamportTime, private readonly lamport: LamportTime,
) {} ) {}
@ -94,7 +91,6 @@ export class OtherConfig implements PinListGetter, NostrEventAdder {
if (err instanceof Error) { if (err instanceof Error) {
return err; return err;
} }
/* no await */ this.nostrEventPusher.put(event);
} }
async removePin(pubkey: string) { async removePin(pubkey: string) {
@ -121,13 +117,11 @@ export class OtherConfig implements PinListGetter, NostrEventAdder {
if (err instanceof Error) { if (err instanceof Error) {
return err; return err;
} }
/* no await */ this.nostrEventPusher.put(event);
} }
static async FromNostrEvent( static async FromNostrEvent(
event: NostrEvent<NostrKind.Encrypted_Custom_App_Data>, event: NostrEvent<NostrKind.Encrypted_Custom_App_Data>,
ctx: NostrAccountContext, ctx: NostrAccountContext,
pusher: Channel<NostrEvent>,
lamport: LamportTime, lamport: LamportTime,
) { ) {
const decrypted = await ctx.decrypt(ctx.publicKey.hex, event.content, "nip4"); const decrypted = await ctx.decrypt(ctx.publicKey.hex, event.content, "nip4");
@ -147,7 +141,7 @@ export class OtherConfig implements PinListGetter, NostrEventAdder {
pinList = []; pinList = [];
} }
const c = new OtherConfig(pusher, ctx, lamport); const c = new OtherConfig(ctx, lamport);
for (const pin of pinList) { for (const pin of pinList) {
const err = await c.addPin(pin); const err = await c.addPin(pin);
if (err instanceof Error) { if (err instanceof Error) {

View File

@ -25,7 +25,7 @@ export type func_IsUserBlocked = (pubkey: PublicKey) => boolean;
type Props = { type Props = {
ctx: NostrAccountContext; ctx: NostrAccountContext;
relay: SingleRelayConnection; relay_url: string;
bus: EventBus<UI_Interaction_Event>; bus: EventBus<UI_Interaction_Event>;
messages: ChatMessage[]; messages: ChatMessage[];
getters: { getters: {
@ -87,7 +87,7 @@ export class PublicMessageContainer extends Component<Props, State> {
<div class={`flex-1 overflow-auto`}> <div class={`flex-1 overflow-auto`}>
{ {
<MessagePanel <MessagePanel
key={props.relay.url} key={props.relay_url}
myPublicKey={props.ctx.publicKey} myPublicKey={props.ctx.publicKey}
emit={props.bus.emit} emit={props.bus.emit}
eventSub={props.bus} eventSub={props.bus}

@ -1 +1 @@
Subproject commit 50df09ad5e6f00408ec3bb95e64251dddf5e841a Subproject commit ca3ca1d6197c0c50b79b25e21b6febccb582a4af