Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
BlowaterNostr committed Apr 29, 2024
1 parent b3178c0 commit 85ed4dc
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 84 deletions.
15 changes: 1 addition & 14 deletions deploy/example.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
import { PublicKey } from "../_libs.ts";
import { run } from "../main.tsx";

const relayed_pubkey = Deno.env.get("relayed_pubkey");
if (!relayed_pubkey) {
console.error("Please set the environment variable 'relayed_pubkey'");
Deno.exit(1);
}

const pubkey = PublicKey.FromString(relayed_pubkey);
if (pubkey instanceof Error) {
console.error(pubkey);
Deno.exit(1);
}

const relay = await run({
port: 8080,
default_policy: {
Expand All @@ -21,7 +8,7 @@ const relay = await run({
default_information: {
name: "Relayed Example",
description: "A lightweight relay written in Deno.",
pubkey,
pubkey: "public key",
contact: "",
icon: "",
},
Expand Down
2 changes: 1 addition & 1 deletion graphql-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const typeDefs = gql`
add_allow(kind: Int, pubkey: String, ): Policy!
remove_allow(kind: Int, pubkey: String, ): Policy!
set_policy(kind: Int, read: Boolean, write: Boolean): Policy!
set_relay_information(name: String, description: String, pubkey: String, contact: String, icon: String): RelayInformation!
set_relay_information(name: String, description: String, contact: String, icon: String): RelayInformation!
}
type Events {
Expand Down
91 changes: 56 additions & 35 deletions main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,25 +48,49 @@ export type Relay = {
block?: Set<string>;
}) => Promise<Policy | Error>;
get_policy: (kind: NostrKind) => Promise<Policy>;
set_relay_information: (args: RelayInformationStringify) => Promise<RelayInformation | Error>;
set_relay_information: (args: {
name?: string;
description?: string;
contact?: string;
icon?: string;
}) => Promise<RelayInformation | Error>;
get_relay_information: () => Promise<RelayInformation | Error>;
default_policy: DefaultPolicy;
};

const ENV_relayed_pubkey = "relayed_pubkey";

export async function run(args: {
port: number;
admin?: PublicKey;
default_information: RelayInformation;
default_policy: DefaultPolicy;
default_information?: RelayInformationStringify;
kv?: Deno.Kv;
}): Promise<Error | Relay> {
const connections = new Map<WebSocket, SubscriptionMap>();
// argument checking
if (args.kv == undefined) {
args.kv = await Deno.openKv();
}

const { port, default_policy, default_information } = args;
let admin_pubkey: string | undefined | PublicKey | Error = args.default_information?.pubkey;
if (admin_pubkey == undefined) {
const env_pubkey = Deno.env.get(ENV_relayed_pubkey);
if (env_pubkey == undefined) {
return new Error(
"public key is not set. Please set env var $relayed_pubkey or pass default_information.pubkey in the argument",
);
}
admin_pubkey = env_pubkey;
}

admin_pubkey = PublicKey.FromString(admin_pubkey);
if (admin_pubkey instanceof Error) {
return admin_pubkey;
}

const { port, default_policy } = args;
///////////////
const connections = new Map<WebSocket, SubscriptionMap>();
let resolve_hostname;
const hostname = new Promise<string>((resolve) => {
resolve_hostname = resolve;
Expand All @@ -76,7 +100,10 @@ export async function run(args: {
const policyStore = new PolicyStore(default_policy, args.kv, await get_all_policies());
const relayInformationStore = new RelayInformationStore(
args.kv,
default_information,
{
...args.default_information,
pubkey: admin_pubkey,
},
);

const eventStore = await EventStore.New(args.kv);
Expand Down Expand Up @@ -152,9 +179,9 @@ async (req: Request, info: Deno.ServeHandlerInfo) => {
if (!body) {
return new Response(`{"errors":"request body is null"}`, { status: 400 });
}
const result = await verifyToken(body, args.relayInformationStore);
if (!result.success) {
return new Response(JSON.stringify(result), { status: 400 });
const error = await verifyToken(body, args.relayInformationStore);
if (error instanceof Error) {
return new Response(JSON.stringify(error.message), { status: 400 });
} else {
const auth = btoa(JSON.stringify(body));
const headers = new Headers();
Expand Down Expand Up @@ -209,9 +236,11 @@ async (req: Request) => {
console.log(`get token: ${token}`);
const event = JSON.parse(atob(token));
console.log(`get event: ${JSON.stringify(event)}`);
const body = await verifyToken(event, args.relayInformationStore);
if (!body.success) {
return new Response(`{"errors":"${body.error}"}`);
const error = await verifyToken(event, args.relayInformationStore);
if (error instanceof Error) {
return new Response(JSON.stringify({
errors: [error.message],
}));
}
const result = await gql.graphql({
schema: schema,
Expand All @@ -221,7 +250,9 @@ async (req: Request) => {
});
return new Response(JSON.stringify(result));
} catch (error) {
return new Response(`{"errors":"${error}"}`);
return new Response(JSON.stringify({
errors: [`${error}`],
}));
}
} else if (req.method == "GET") {
const res = new Response(graphiql);
Expand Down Expand Up @@ -264,29 +295,19 @@ const information_handler = async (args: { relayInformationStore: RelayInformati
};

async function verifyToken(event: NostrEvent, relayInformationStore: RelayInformationStore) {
try {
if (!await verifyEvent(event)) {
throw new Error("token not verified");
}
const pubkey = PublicKey.FromString(event.pubkey);
if (pubkey instanceof Error) {
throw new Error("pubkey not valid");
}
const storeInformation = await relayInformationStore.resolveRelayInformation();
if (storeInformation instanceof Error) {
throw new Error("store pubkey not valid");
}
if (pubkey.hex !== storeInformation.pubkey.hex) {
throw new Error("not admin");
}
return {
success: true,
};
} catch (error) {
return {
success: false,
error: error.toString(),
};
if (!await verifyEvent(event)) {
return new Error("token not verified");
}
const pubkey = PublicKey.FromString(event.pubkey);
if (pubkey instanceof Error) {
return pubkey;
}
const storeInformation = await relayInformationStore.resolveRelayInformation();
if (storeInformation instanceof Error) {
return storeInformation;
}
if (pubkey.hex !== storeInformation.pubkey.hex) {
return new Error("your pubkey is not an admin");
}
}

Expand Down
50 changes: 16 additions & 34 deletions resolvers/nip11.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ export type RelayInformationParsed = {
} & RelayInfomationBase;

export type RelayInformation = {
pubkey: PublicKey;
name?: string;
description?: string;
pubkey: PublicKey;
contact?: string;
supported_nips?: number[];
software?: string;
Expand All @@ -37,55 +37,37 @@ const not_modifiable_information: {
};

export class RelayInformationStore {
default_information: RelayInformation;

constructor(
private kv: Deno.Kv,
default_information: RelayInformation,
) {
this.default_information = default_information;
}
public default_information: RelayInformation,
) {}

resolveRelayInformation = async (): Promise<RelayInformation | Error> => {
const store_information_i =
(await this.kv.get<RelayInformationStringify>(["relay_information"])).value;
if (!store_information_i) {
const entry = await this.kv.get<RelayInfomationBase>(["relay_information"]);
if (!entry.value) {
return { ...this.default_information, ...not_modifiable_information };
}
const store_information = informationPubkeyParse(store_information_i);
if (store_information instanceof Error) {
return store_information;
}
return { ...this.default_information, ...store_information, ...not_modifiable_information };

return { ...this.default_information, ...entry.value, ...not_modifiable_information };
};

set_relay_information = async (args: RelayInformationStringify): Promise<RelayInformation | Error> => {
set_relay_information = async (args: {
name?: string;
description?: string;
contact?: string;
icon?: string;
}): Promise<RelayInformation | Error> => {
const old_information = await this.resolveRelayInformation();
if (old_information instanceof Error) {
return old_information;
}
const input_information = informationPubkeyParse(args);
if (input_information instanceof Error) {
return input_information;
}
const new_information = { ...old_information, ...input_information };
const store_new_information = informationPubkeyStringify(new_information);
await this.kv.set(["relay_information"], store_new_information);

const new_information = { ...old_information, ...args };
await this.kv.set(["relay_information"], new_information);
return { ...new_information, ...not_modifiable_information };
};
}

export function informationPubkeyParse(info: RelayInformationStringify): RelayInformationParsed | Error {
if (!info.pubkey) {
return info as RelayInfomationBase;
}
const pubkey = PublicKey.FromString(info.pubkey);
if (pubkey instanceof Error) {
return pubkey;
}
return { ...info, pubkey };
}

export function informationPubkeyStringify(info: RelayInformationParsed): RelayInformationStringify {
if (!info.pubkey) {
return info as RelayInfomationBase;
Expand Down

0 comments on commit 85ed4dc

Please sign in to comment.