maybe working?

This commit is contained in:
zmeyer44 2023-10-18 14:14:17 -04:00
parent d8f9ea6d40
commit 50329b9e4e
12 changed files with 225 additions and 26 deletions

View File

@ -0,0 +1,23 @@
import Subscriptions from "@/containers/Subscriptions";
import Spinner from "@/components/spinner";
import Link from "next/link";
import { NDKEvent } from "@nostr-dev-kit/ndk";
import { ReactElement } from "react";
export default function ProfileSubscriptions({ pubkey }: { pubkey: string }) {
return (
<div className="sm:md-feed-cols relative flex flex-col gap-3">
<Subscriptions
link={true}
pubkey={pubkey}
loader={() => (
<div className="center flex-col gap-y-4 pt-7 text-center">
<Spinner />
<p className="font-medium text-primary">
Fetching Subscriptions...
</p>
</div>
)}
/>
</div>
);
}

View File

@ -8,6 +8,7 @@ import Tabs from "@/components/Tabs";
import useProfile from "@/lib/hooks/useProfile";
import { getTwoLetters, truncateText } from "@/lib/utils";
import ProfileFeed from "./_components/Feed";
import Subscriptions from "./_components/Subscriptions";
import { nip19 } from "nostr-tools";
export default function ProfilePage({
@ -114,7 +115,7 @@ export default function ProfilePage({
</div>
</div>
<div className="mx-auto max-w-[800px] space-y-6">
<div className="flex max-w-2xl flex-col gap-5">
<div className="flex max-w-2xl flex-col gap-5 px-5">
{demo.map((e) => (
<SubscriptionCard key={e.id} {...e} />
))}
@ -126,10 +127,6 @@ export default function ProfilePage({
name: "feed",
label: "Feed",
},
{
name: "media",
label: "Media",
},
{
name: "subscriptions",
label: "Subscriptions",
@ -140,6 +137,7 @@ export default function ProfilePage({
/>
</div>
{activeTab === "feed" ? <ProfileFeed pubkey={pubkey} /> : ""}
{activeTab === "subscriptions" ? <Subscriptions pubkey={pubkey} /> : ""}
</div>
</div>
);

View File

@ -46,7 +46,8 @@ export default function ListPage({
);
}
const noteIds = getTagsValues("e", event.tags).filter(Boolean);
console.log("notes", event.tags);
console.log("notes", noteIds);
console.log("tags", event.tags);
return (
<div className="relative mx-auto max-w-5xl space-y-4 p-2 sm:p-4">

BIN
bun.lockb

Binary file not shown.

View File

@ -1,18 +1,119 @@
"use client";
import { useState, useEffect } from "react";
import Link from "next/link";
import Container from "./components/Container";
import { CardTitle, CardDescription } from "@/components/ui/card";
import { type Event } from "nostr-tools";
import { cn } from "@/lib/utils";
import { useNDK } from "@/app/_providers/ndk";
import { RiArrowRightLine, RiLockLine } from "react-icons/ri";
import { decryptMessage } from "@/lib/nostr";
import { NDKUser } from "@nostr-dev-kit/ndk";
export default function Kind3745({ pubkey }: Event) {
import { EventSchema } from "@/types";
import KindCard from "@/components/KindCard";
import Spinner from "../spinner";
export default function Kind3745(props: Event) {
const { pubkey, content, id } = props;
const [error, setError] = useState("");
const [fetchingEvent, setFetchingEvent] = useState(false);
const [decryptedEvent, setDecryptedEvent] = useState<Event>();
const { ndk } = useNDK();
useEffect(() => {
if (ndk && !fetchingEvent && !decryptedEvent) {
void handleFetchEvent();
}
}, [ndk]);
async function handleFetchEvent() {
setFetchingEvent(true);
try {
const directMessageEvent = await ndk!.fetchEvent({
kinds: [4],
authors: [pubkey],
["#e"]: [id],
});
if (directMessageEvent) {
await directMessageEvent.decrypt(
new NDKUser({ hexpubkey: pubkey }),
ndk?.signer,
);
const passphrase = directMessageEvent.content;
if (!passphrase) {
setError("Unable to parse event");
return;
}
const decrypedData = await decryptMessage(content, passphrase);
console.log("Decrypted", decrypedData);
const hiddenEvent = EventSchema.safeParse(
JSON.parse(decrypedData ?? ""),
);
if (hiddenEvent.success) {
setDecryptedEvent(hiddenEvent.data);
} else {
setError("Unable to parse event");
}
}
} catch (err) {
setError("Unable to parse event");
} finally {
setFetchingEvent(false);
}
}
if (decryptedEvent) {
return <KindCard {...decryptedEvent} />;
}
return (
<Container pubkey={pubkey}>
<div className="relative ">
<div className=" blur">
<CardTitle className="mb-1.5 line-clamp-2 text-lg font-semibold">
The start of the Nostr revolution
</CardTitle>
<CardDescription className="line-clamp-4 text-sm">
This is the summary of this artilce. Let's hope that it is a good
article and that it will end up being worth reading. I don't want to
waste my time on some random other stuff.
Here is some secret text. If you are reading this, that means you've
tried some sneaky css tricks to reveal what was hidden 🫣.
Unfourtunatly, CSS won't be able to help you here. In fact, I can't
even reveal this if I wanted to. Only the correct private key can
reveal it.
</CardDescription>
</div>
<div className="center absolute inset-0">
{fetchingEvent ? (
<div className="center">
<Spinner />
</div>
) : (
<Link href={`/`} className="group flex rounded-md shadow-sm">
<div
className={cn(
"flex w-14 flex-shrink-0 items-center justify-center rounded-l-md bg-primary text-sm font-medium text-background",
)}
>
<RiLockLine className="h-5 w-5" aria-hidden="true" />
</div>
<div className="flex flex-1 items-center justify-between truncate rounded-r-md border border-b border-r border-t bg-background">
<div className="flex-1 truncate px-4 py-2 text-sm">
<a className="font-medium text-foreground group-hover:text-primary">
Content locked
</a>
<p className="text-gray-500">Subscribe to reveal</p>
</div>
<div className="flex-shrink-0 pr-2">
<button
type="button"
className="inline-flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground group-hover:text-primary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
>
<span className="sr-only">Open options</span>
<RiArrowRightLine className="h-5 w-5" aria-hidden="true" />
</button>
</div>
</div>
</Link>
)}
</div>
</div>
</Container>
);
}

View File

@ -60,10 +60,12 @@ export default function Container({
<CardContent className="flex grow flex-col px-4 pb-3">
{children}
<div className="mt-auto">
{!!contentTags?.length && (
{!!contentTags?.length ? (
<div className="mb-2.5 mt-1 max-h-[52px] overflow-hidden">
<Tags tags={contentTags} />
</div>
) : (
<div className="h-1.5" />
)}
<div className="border-t">
<Actions />

View File

@ -77,7 +77,7 @@ export default function ShortTextNoteModal() {
});
}
}
console.log("about to create private event with ", listSigner);
const result = await createEventHandler(
ndk,
{

View File

@ -0,0 +1,61 @@
"use client";
import KindCard from "@/components/KindCard";
import { cn } from "@/lib/utils";
import Link from "next/link";
import Spinner from "@/components/spinner";
import { Event } from "nostr-tools";
import useEvents from "@/lib/hooks/useEvents";
import NDK, { NDKEvent, type NDKFilter } from "@nostr-dev-kit/ndk";
import ListCard from "@/components/ListCard";
type SubscriptionsProps = {
pubkey: string;
link?: boolean;
className?: string;
loader?: () => JSX.Element;
empty?: () => JSX.Element;
};
export default function Subscriptions({
pubkey,
link = false,
className,
loader: Loader,
empty: Empty,
}: SubscriptionsProps) {
const { events, isLoading } = useEvents({
filter: {
kinds: [30001],
["#p"]: [pubkey],
},
});
if (isLoading) {
if (Loader) {
return <Loader />;
}
return <Spinner />;
}
if (Empty && events.length === 0) {
return <Empty />;
}
if (link) {
return (
<>
{events.map((e) => {
return (
<Link href={`/list/${e.encode()}`}>
<ListCard key={e.id} event={e} />;
</Link>
);
})}
</>
);
}
return (
<>
{events.map((e) => {
return <ListCard key={e.id} event={e} />;
})}
</>
);
}

View File

@ -58,7 +58,7 @@ export async function createEventHandler(
}
const eventToPublish = new NDKEvent(ndk, {
...event,
tags: [...event.tags, ["client", "ordstr"]],
tags: [...event.tags, ["client", "flockstr"]],
pubkey,
created_at: unixTimeNowInSeconds(),
} as NostrEvent);
@ -68,20 +68,27 @@ export async function createEventHandler(
let publishedEvent: NDKEvent | null = null;
// Check if is private event
if (isPrivate) {
console.log("isPrivate");
const rawEventString = JSON.stringify(eventToPublish.rawEvent());
console.log("rawEventString", rawEventString);
const passphrase = generateRandomString();
console.log("passphrase", passphrase);
const encryptedRawEventString = await encryptMessage(
rawEventString,
passphrase,
);
console.log("encryptedRawEventString", encryptedRawEventString);
console.log("delegateSigner", delegateSigner);
const signer = delegateSigner ?? ndk.signer!;
const user = await signer.user();
console.log("signer user", user);
const newEvent = new NDKEvent(ndk, {
content: encryptedRawEventString,
kind: 3745,
tags: [
["kind", event.kind.toString()],
["client", "ordstr"],
["client", "flockstr"],
],
pubkey: user.pubkey,
} as NostrEvent);
@ -98,7 +105,7 @@ export async function createEventHandler(
tags: [
["p", subscriber],
["e", newEvent.id],
["client", "ordstr"],
["client", "flockstr"],
],
pubkey: user.pubkey,
} as NostrEvent);
@ -141,7 +148,7 @@ export async function createEncryptedEventOnPrivateList(
}
const eventToPublish = new NDKEvent(ndk, {
...event,
tags: [...event.tags, ["client", "ordstr"]],
tags: [...event.tags, ["client", "flockstr"]],
pubkey,
created_at: unixTimeNowInSeconds(),
} as NostrEvent);
@ -160,7 +167,7 @@ export async function createEncryptedEventOnPrivateList(
kind: 3745,
tags: [
["kind", event.kind.toString()],
["client", "ordstr"],
["client", "flockstr"],
],
pubkey: user.pubkey,
} as NostrEvent);
@ -186,7 +193,7 @@ export async function createEncryptedEventOnPrivateList(
tags: [
["p", subscriber],
["e", newEvent.id],
["client", "ordstr"],
["client", "flockstr"],
],
pubkey: user.hexpubkey,
} as NostrEvent);

View File

@ -103,7 +103,7 @@ async function generateTags(mainSigner: NDKSigner, opts: ISaveOpts = {}) {
const mainUser = await mainSigner.user();
const tags = [
["p", mainUser.hexpubkey],
["client", "ordstr"],
["client", "flockstr"],
];
if (opts.associatedEvent) {

View File

@ -119,6 +119,7 @@ export function encryptMessage(message: string, password: string) {
}
// Function to decrypt a hashed message using a passphrase
export function decryptMessage(encryptedMessage: string, password: string) {
console.log("Attemping decrypto", encryptedMessage, "with", password);
try {
const buffer = create32ByteBuffer(password);
// Extract IV from the received message
@ -130,11 +131,15 @@ export function decryptMessage(encryptedMessage: string, password: string) {
const iv = Buffer.from(ivBase64, "base64");
const encryptedText = Buffer.from(encryptedMessage, "base64");
console.log("at bugger");
const decipher = crypto.createDecipheriv("aes-256-cbc", buffer, iv);
console.log("at decipher");
const decrypted = decipher.update(encryptedText);
return Buffer.concat([decrypted, decipher.final()]).toString();
const toReturn = Buffer.concat([decrypted, decipher.final()]).toString();
console.log("toReturn", toReturn);
return toReturn;
} catch (e) {
console.error(e);
}

View File

@ -33,6 +33,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"cmdk": "^0.2.0",
"crypto": "^1.0.1",
"crypto-js": "^4.1.1",
"dayjs": "^1.11.10",
"focus-trap-react": "^10.2.3",